CakePHP1.2流Fixure
前回ちょっとだけテストケース作りましたが、やっぱりRailsのFixtureのような機能がほしい。
Testing Models with CakePHP 1.2 test suite
上の記事が詳しく、基本的にマネすればいいのですが、ハマりポイントもアリ。まだalpha版ってことなので、目くじら立てるほどでもないけど、どう動いてるのかわからず、ややウザな検証が必要でした。
ということで、ブログチュートリアルで作ったPostをテストするメモ。
CakePHPバージョンは、1.2.0.5146alpha です。
■app/models/Post.php
<?php
class Post extends AppModel {
var $name = "Post";
}
?>
コンフィグレーションの件
■app/config/database.php
class DATABASE_CONFIG {
var $default = array(
'database' => 'cake',
);
var $test = array(
'database' => 'cake_test',
);
}
まず、app/config/database.phpの設定ですが、$testの方は「設定されていれば使う・されていなければ使わない」という、ゆるーい仕様です。$testを消しても、$defaultの方でテストできてしまいます。
どちらのDBを使うにしても'test_suite_'という固定のプレフィックスがついたテスト用テーブルが自動作成されるので、既存テーブルを壊したりしません。※Railsユーザーには違和感ポイント。Fatalとかでテストが止まらない限り、気づかない...
Fixtureを使ったテストケース
■app/tests/cases/models/PostTestCase.php
<?php
loadModel('post');
//Postにテスト用の設定をオーバライドする。
class PostTest extends Post {
var $name = 'Post';
//→ 使うテーブル名は'test_suite_posts'になる。
//$testまたは$defaultを使う設定。
var $useDbConfig = 'test_suite';
//→ $tablePrefixが自動で'test_suite_'に。
//または、テストで使うDBを明示できる
// var $useDbConfig = 'test'; //database.phpで定義した名前
// var $tablePrefix = 'test_suite_'; //固定
}
class PostTestCase extends CakeTestCase {
//PostFixture.php(下記参照)でデータロード
var $fixtures = array( 'post' );
function testSomething() {
$this->Post = new PostTest(); //new Post() ではなく
$this->Post->save(array('id'=>'1','title'=>'aaaaaa'));
$this->assertTrue($this->Post->findById(1));
}
}
?>
Postをそのままテストすると、$default.postsテーブルを使ってテストが走ってしまいます。$useDbConfig = 'test_suite'と上書きすると、($test or $default).test_suite_postsテーブルでテストが走ります。
それで、あとは、継承クラスに対してテストコードを書きます。
Fixtureがやってること
■app/tests/fixtures/PostFixture.php
<?php
class PostFixture extends CakeTestFixture {
//test_suite_postsというテーブル名で
var $name = 'Post';
//$default.postsからスキーマをコピー
var $import = array('model'=>'Post');
//または、レコードもコピー
//var $import = array('model'=>'Post', 'records'=>true);
/* または、コピーではなく自作もできる。
var $fields = array(
'id' => array('type' => 'integer', 'key' => 'primary'),
'title' => array('type' => 'string', 'length' => 255, 'null' => false),
'body' => 'text',
'created' => 'datetime',
'updated' => 'datetime'
);
var $records = array(
array ('id' => 1, 'title' => '11111'),
array ('id' => 2, 'title' => '22222')
);
*/
}
?>
$defaultの既存のテーブルを$importすると、テスト用のテーブルとしてテーブルのコピーを作成します。$importの代わりに、(Rails Migrateの要領で)自分でスキーマを作って$recordsを挿入することもできます。
$importしたテーブルに$recordsを書き込めるとサイコーなのですが、残念ながら現時点では動作しませんでした。
(※挿入はしてるんだけど、テストメソッドが走る直前に消えてしまう。フックの順番が間違っているようだ・・・)