Fixture系モジュールはコールバックで値を入れられる方がいい
例えば日付に絡むテストをしたい時、ダミーデータとしてハードコードしてしまうと、後々、データが古いというだけでテストがコケるという可能性が出てくる。
まあ、可能性というか、実際今僕のところで起きたんだけどさ。
もうちょっと具体例を挙げると、週間ランキングのロジックをテストをしたいとかいうとき、ギリギリ3,4日後くらいまではなんとかなっても、もし1ヶ月先に何らかの事情でそのテストを回したいとき、そんなところで落ちてたら、無駄に原因究明の時間を使う事になる。
ということで、DBIx::MoCo::Fixtureのload_fixtureをちょっと弄る。
{ package DBIx::MoCo::Fixture; use Data::Visitor::Callback; our $Substitutions = {}; sub append_substitutions { my ( $key, $callback ) = @_; $Substitutions->{$key} = $callback; } no warnings 'redefine'; sub load_fixture { my $file = shift; my $yaml = $file->slurp or die $!; Data::Visitor::Callback->new( plain_value => sub { return unless defined $_; for my $sig ( keys %$Substitutions ) { if(/__${sig}\((.+?)\)__/) { return $Substitutions->{$sig}->($1); } } return $_; } )->visit( YAML::Syck::Load($yaml) ); } } DBIx::MoCo::Fixture::append_substitutions( add => sub { my $val = shift; require DBIx::MoCo::Column::DateTime; return DBIx::MoCo::Column::DateTime->DateTime_as_string( DateTime->now->set_time_zone('Asia/Tokyo')->add( eval "($val)" ) ); } );
こんな風にしておくと、
--- created_on: __add(days => -3)__
というのが
--- created_on: 2009-03-27 18:32:32
となってくれる。てか、Catalyst::Plugin::ConfigLoaderでやってることそのまんまっすね><
あ、あと、evalはご愛嬌ということでお願いします><
(追記)
これ、たまたま僕が今使ってるO/R MapperがMoCoなので、MoCoのコード例として出しましたけど、Test::Fixture::DBIC::SchemaとかDBIx::Class::Fixtureとか、ダミーデータをハードコードさせるモジュール全てに言えることですので。