tsucchi’s diary(元はてなダイアリー)

はてなダイアリー(d.hatena.ne.jp/tsucchi1022)から移行したものです

Teng の Row オブジェクトをテストする

最近、わりと普通な感じの web アプリを書いてたりします。で、Teng 使ってたりします。

Teng は Row オブジェクトにあれこれ機能を追加したりできて便利なのですが、ちょっと難しいロジックが入ったりするとテストを書きたくなってきます。そこで、こんなものを書いてみました。*1

package t::Util::TengRow;
use parent qw(Exporter);
use strict;
use warnings;
use utf8;
use DBI;
use MyProj::DB;# Teng のサブクラス

our @EXPORT = qw(row_from_hashref);

sub row_from_hashref {
    my ($table_name, $row_value_href) = @_;
    my $dbh = DBI->connect('DBI:Mock:', '', '');
    my $teng = MyProj::DB->new(dbh => $dbh);
    my $table = $teng->{schema}->get_table($table_name);

    my $row_data = {};
    for my $column ( @{ $table->{columns} } ) {
        $row_data->{$column} = $row_value_href->{$column};
    }

    return $table->{row_class}->new({
        sql        => "SELECT * FROM $table_name",
        row_data   => $row_data,
        teng       => $teng,
        table      => $table,
        table_name => $table_name,
    });
}

1;

テストコード側はこんな感じです。

use strict;
use warnings;
use t::Util::TengRow;

subtest 'add', sub {
    my $row = row_from_hashref('some_table', { value1 => 1, value2 => 2 });
    #add_value1_and_value2 は名前のとおり value1 と value2 を加算した結果を返すメソッドとします
    is( $row->add_value1_and_value2, 3 ); 
};
done_testing();

まあ、この例のレベルならテストコードいらないよねー*2、とか、$row->handle 経由であれこれするようなやつはアウトだとか、DBD::Mock 仕事してないじゃん*3、とか色々問題はあるのですが、とりあえずこんなの使ってますよ、と。

*1:Teng#single メソッドの Row オブジェクト生成部分をパクってテスト用に調整しただけです

*2:どのくらい難しい処理だったらテストを書くべきか悩むよね、と言う意味で

*3:仕事してないからいらない気もするし、かと言って空文字とか undef とか渡すのも怪しいし、でも通常利用してる DBD を渡すのはそれはそれで気持ち悪いし、悩みます