LoginSignup
3
4

More than 5 years have passed since last update.

CakePHP3でコントローラーのテストにモックを使う

Posted at

CakePHP3になって、セッションの設定も簡単にできるようになったし、テストが簡単に書ける!
…と思ったのですが、CakePHP2だとgenerate()でできていたコントローラーのテストにおけるモックの使い方が、3ではイマイチ不明…。
exec()でシェルコマンドを呼んでいるところ(メール送信処理)をテストで実行したくなかったので、とりあえず以下のようにしてみました。

BookingsController.php
public function add()
{
    $booking = $this->Bookings->newEntity();
    if ($this->request->is('post')) {
        $booking = $this->Bookings->patchEntity($booking, $this->request->data);
        if ($result = $this->Bookings->save($booking)) {
            // メール送信
            $this->_shell('booking_email send ' . $result->id);
            return $this->redirect(['action' => 'comp']);
        } else {
            $this->Flash->error('The inquiry could not be saved. Please, try again.');
        }
    }
}

protected function _shell($shell)
{
    exec(ROOT . '/bin/cake ' . $shell . ' > /dev/null &');
}
BookingsControllerTest.php
public function testAdd()
{
    $data = [
        'name' => 'Yamada Taro',
        'email' => 'test@example.com'
    ];
    $this->_request = $this->_buildRequest('/bookings/add', 'POST', $data);
    $this->_response = new Response();
    $controller = $this->getMock('App\Controller\BookingsController', ['_shell'], [$this->_request, $this->_response]);
    $controller->loadModel('Bookings');
    $controller->expects($this->once())
        ->method('_shell')
        ->with($this->equalTo('booking_email send 2'));
    $controller->add();
    $this->assertRedirect(['action' => 'comp']);
}

せっかくの$this->post('/bookings/add', $data)とか書けないし、漂う無理やり感…。
もっと美しく書けないのかなぁ。

参考:Cookbook 3.x - Testing

3
4
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
3
4