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)
とか書けないし、漂う無理やり感…。
もっと美しく書けないのかなぁ。