CakePHP2でユニットテスト 〜バリデーション編〜

まだまだあけましておめでとうございます。 年始をいかがお過ごしでしょうか。

私はいつものように、日常と変わらない生活をしています。

さてさて、ユニットテストの件ですが、以前更新して随分時間が経ってしまいましたが、書いていこうかなぁと思います。

今回はバリデーションをテストするための方法を書こうと思います。 前回の routes.php に対するテストの記事は以下になります。 CakePHP2でユニットテスト 〜route.php編〜

バリデーションを適応していく

今回はUserモデルに対してnamenotEmptyを、telに対して独自のバリデーションであるcheckNotEmptynumericOnlyを適応していると仮定します。

User.php

App::uses('AppModel', 'Model');

class User extends AppModel {
    public $validate = [
        'name' => [
            'rule' => ['notEmpty'],
            'message' => '名前を入力して下さい。'
        ],
        'tel1' => [
            'notEmpty' => [
                'rule' => ['checkNotEmpty'],
                'message' => '電話番号を入力して下さい。'
            ],
            'numericOnly' => [
                'rule' => ['numericOnly'],
                'message' => '数字のみ入力して下さい。'
            ]
        ]
    ];

    public function checkNotEmpty(){
        if(!empty($this->data[$this->alias]['tel1']) && 
           !empty($this->data[$this->alias]['tel2']) && 
           !empty($this->data[$this->alias]['tel3'])) {
            return true;
        } else {
            return false;
        }
    }

    public function numericOnly(){
        // 数字のみ許可
        $pattern = '/^[0-9]+$/';
        $tel1 = preg_match($pattern, $this->data[$this->alias]['tel1']);
        $tel2 = preg_match($pattern, $this->data[$this->alias]['tel2']);
        $tel3 = preg_match($pattern, $this->data[$this->alias]['tel3']);
        if(empty($tel1) && empty($tel2) && empty($tel3)){
           return true;
        } else {
           return false;
        }
    }
}

こういうモデルに対してテストを書いていこうと思います。

バリデーションに対するモデルを書く

テストを書いていきます。

Test/Case/Model/UserTest.php

App::uses('User', 'Model');

class UserTest extends CakeTestCase {

    public function setUp() {
        parent::setUp();
        $this->User = ClassRegistry::init('User');
    }

    public function tearDown() {
        unset($this->User);
        parent::tearDown();
    }

    public function testUserValidations(){
        $baseCase = [
            'name' => '佐藤'
            'tel1' => '090'
            'tel2' => '0088'
            'tel3' => '8800'
        ];

        $testCases = [
            true => [
                ['name' => '谷'],
                ['tel1' => '03', 'tel2' => '1111', 'tel3' => '2222']
            ],
            false => [
                ['name' => ''],
                ['tel1' => ''],
                ['tel2' => -1]
            ]
        ];

        foreach($testCases as $expected => $cases){
            foreach($cases as $case){
                $testCase = array_merge($baseCase, $case);
                $this->User->set($testCase);
                $result = $this->Entry->validates();
                if((boolean)$expected){
                    $this->assertTrue($result);
                } else {
                    $this->assertFalse($result);
                }
            }
        }
    }

}

こんな感じでテストを書いていきます。 このやり方であればテストケースを変更するのも簡単だし、trueとfalseで固まっているのでわかりやすいかと思います。

最後に

いかがでしたでしょうか。

今回もroutes.phpのテストと同じく、直感的でわかりやすかったかと思います。 ユニットテストは自分が安心するのもありますし、機能毎の詳細な仕様書にもなります。 なのでしっかりテストを書いていきましょう。(面倒くさいけど)

CakePHPで新しい本が出てました。読まねば。