LoginSignup
11
8

More than 5 years have passed since last update.

CakePHPでモデルのUnitTestを行う

Last updated at Posted at 2016-02-15

モデルを作成

  • app/Model/Article.phpを作成
<?php
class Article extends AppModel {
    public function published($fields = null) {
        $params = array(
            'conditions' => array(
                $this->name . '.published' => 1
            ),
            'fields' => $fields
        );

        return $this->find('all', $params);
    }
}

フィクスチャを作成

  • テストに使うための一時的なデータをロードするためのもの
  • 実データを使わずにデータベースが必要な機能をテストできる
  • app/Test/Fixture配下に作成する([Model名]Fixture)
  • app/Config/database.phpにある$testのデータベース接続情報を使う
  • フィクスチャでは以下の2点を記述する
    • フィールド情報
    • 初期状態で用意するレコードデータ
<?php
class ArticleFixture extends CakeTestFixture {
      public $fields = array(
          'id' => array('type' => 'integer', 'key' => 'primary'),
          'title' => array(
            'type' => 'string',
            'length' => 255,
            'null' => false
          ),
          'body' => 'text',
          'published' => array(
            'type' => 'integer',
            'default' => '0',
            'null' => false
          ),
          'created' => 'datetime',
          'updated' => 'datetime'
      );
      public $records = array(
          array(
            'id' => 1,
            'title' => 'First Article',
            'body' => 'First Article Body',
            'published' => '1',
            'created' => '2007-03-18 10:39:23',
            'updated' => '2007-03-18 10:41:31'
          ),
          array(
            'id' => 2,
            'title' => 'Second Article',
            'body' => 'Second Article Body',
            'published' => '1',
            'created' => '2007-03-18 10:41:23',
            'updated' => '2007-03-18 10:43:31'
          ),
          array(
            'id' => 3,
            'title' => 'Third Article',
            'body' => 'Third Article Body',
            'published' => '1',
            'created' => '2007-03-18 10:43:23',
            'updated' => '2007-03-18 10:45:31'
          )
      );
 }
  • テストデータベース以外の既存のデータベース(デフォルトテーブル)を利用したい場合
      //デフォルトテーブルに存在するテーブルのフィールド情報を読み込む
      public $import = ['table' => 'articles'];
      public $records = [];
  • 上記のようにしておくと既存テーブルの構成を使ってデータが生成される

テスト用クラスを作成

  • app/Test/Case/Model/[Model名]Test.php
<?php
//テスト対象のモデルをインポート
App::uses('Article', 'Model');
//外部ライブラリ
App::uses('Fabricate', 'Fabricate.Lib');

class ArticleTest extends CakeTestCase {
    public $fixtures = array('app.article');

    //テスト実行前に毎回呼ばれる
    public function setUp() {
        //親のsetUpは必ず呼び出す
        parent::setUp();
    }

    //testXXの名前にする
    public function testPublished() {
        $expected = array(
            array('Article' => array('id' => 1, 'title' => 'First Article')),
            array('Article' => array('id' => 2, 'title' => 'Second Article')),
            array('Article' => array('id' => 3, 'title' => 'Third Article'))
        );
        //モックを使うパターン
        $model = $this->getMockForModel('Article', array('published'));
        //先に呼び出す回数と期待する値をセット
        $model
            ->expects($this->once())
            ->method('published')
            ->will($this->returnValue($expected));
        //実行する
        $result = $model->published(array('id', 'title'));

        //テーブルにモックデータを保存して結果を返す。実際のテーブルに保存されるわけではない
        //件数指定しない場合は1件
        Fabricate::create('Article', function($data, $world) {
            //取得結果を変更したり出来る
            return [
                'id' => 1
                'name' => 'test'
            ];
        });
        $articles = $this->Article->find('all');
    }
}
  • 事前に用意したデータだけでテストするのであれば、フィクスチャでレコードを用意しておくだけでいいが、自分でテストデータを追加したりしたい時も多い
  • そんな場合はこのライブラリを使う。作成されるデータはスキーマ情報から自動判定されて適当な初期値が入る
  • 値を変えたい場合は、コールバックで変更が可能
  • 作成する件数は第二引数で指定できる。デフォルトは1件 https://github.com/sizuhiko/Fabricate
11
8
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
11
8