Test::DataLoader::MySQL というモジュールを書いた
意外と早くアップロードされたなぁ。CPAN Author になりました。
Test::DataLoader::MySQL - search.cpan.org
これは何か、というと、テストコード中でテストデータをDBに流し込むためのモジュールです。
最近のお仕事の話とかデータベースのテストの話とかに少し書きましたが、今のウチのプロジェクトはモデルが DB のテーブルそのもので、ビジネスロジックがストアドプロシージャに書いてあったりします。
こういう環境では、モックオブジェクトが使えず、DB に直接データを流し込む以外にテストする方法がありません(多分)。また、安易にモジュールがインストールできない環境のために、依存するモジュールをなるべく少なくたいという(自分の)要望があって、そうしています。(DBI と DBD::mysql が入っていれば動くはず。テストコードを動かすためには Test::mysqld が入っているほうが望ましいですが)。
一応怪しい英語で POD にたくさんドキュメントを書いたけど、わかりにくいと思うので、ここでも解説してみます。
基本的な使い方はこんな感じ。
my $data = Test::DataLoader::MySQL->new($dbh); # DBI からもらった handler を new に渡して。。。 # add します。このタイミングでは、モジュールにデータを教えているだけ。実際にDB には入れません $data->add('foo', #テーブル名 1, #データID {# 流し込みたいデータ(data_href: column => value) id => 1, name => 'aaa', }, ['id']); # 主キー(array_ref) $data->load('foo', 1); #さっき登録した、テーブル名'foo', データID'1' のデータを DB に流し込みます # ... # で、あとは好きなだけテスト書く
データ ID はただのハッシュのキーなので、何でもいいです。私のプロジェクトでは数字を使っていました。
デフォルトでは、流し込んだデータはオブジェクト(ここでの例なら $data)が破棄されるタイミングで DELETE されます。データ削除は、add メソッドの最後の引数の array_ref をキーにして DELETE 文を発行しています。
なので、キーなしのテーブルの場合もテストデータ内で一意になるような擬似的なキーを決めて書くようにしてください。
new にオプションで Keep=>1 と指定すれば、オブジェクトが破棄されてもデータは残ります。
my $data = Test::DataLoader::MySQL->new($dbh, Keep=>1); #こうするとデータが残る
主キーがオートナンバー(AUTO_INCREMENT)の場合は、load メソッドの戻り値を使います。
my $data = Test::DataLoader::MySQL->new($dbh); $data->add('foo', 1, { name => 'aaa', }, ['id']); my $key = $data->load('foo', 1); my $id = $key->{id}; #ここでオートナンバーで設定される値(キーのid)が $id に入る
複数のテストで共通のテストデータを使いまわしたい場合は、そのファイルで add します。この場合はコンストラクタ new の代わりに init を呼んでください。たとえば、下記のような内容で、testdata.pm を作ります。
# testdata.pm my $data = Test::DataLoader::MySQL->init(); #外部ファイルでは new ではなくinit を使う $data->add('foo', 1, { id => 1, name => 'aaa', }, ['id']); $data->add('foo', 2, { id => 2, name => 'bbb', }, ['id']); # ...こんな感じでデータをたくさん登録
で、テストコード側では、load_file で、さっき登録したデータを読み込みます。
# in your testcode my $data = Test::DataLoader::MySQL->new($dbh); $data->load('foo', 1); #使うデータだけロードすればよい # ...でデータを使うテストを書く
ほとんどのテストコードで使う共通ファイルを外部に置き、あるテストコードに固有のデータはそこで add するほうが多分わかりやすいです。ウチのプロジェクトは単一ファイルに置いて、ハイパーカオスを作り上げてしまいましたが。。。
わからない点があれば、テストコードを見るのが早いと思います。テストコードに書いてある以上の機能は作りこんでいないので。
今回はプロジェクトで使っていたものをベースに、書き直しをしたものではありますが、基本的な考え方やインターフェースは変えていません。コレの元ねたのモジュールを使って、400 ファイルくらいのテストコードを書いているので結構実績もあるはず。
とはいえ、書き直しているので、もしかすると全然ダメダメかもしれません。その場合は RT でもメールでも何でも良いのでご連絡をお願いします。