集成测试中的 CakePHP 3 模拟方法
CakePHP 3 mocking methods in integration tests
我目前正在使用集成测试用例来测试某些端点上的响应,但不知道如何使用模拟方法来停止测试以及发送电子邮件等操作。
我的测试方法类似如下:
public function testInviteUser() {
$this->post('/invite-user', [
'name' => 'Joe Bloggs',
'email' => 'joe@bloggs.com'
]);
$this->assertRedirect([
'controller' => 'Users',
'action' => 'index'
]);
}
UsersTable
class 正在使用 Mailer
侦听 afterSave
事件并发送电子邮件。是否可以使用模拟对象来解决这个问题?我了解在其他地方进行单元测试时如何使用它们,但看不到文档中的示例如何适合集成测试。
没有找到方法来做到这一点,我使用了以下解决方案。
在名为 TESTING
的测试 bootstrap.php
中定义了一个常量,然后使用 defined('TESTING')
来确定是否应该发送电子邮件。不理想,因为我确定这可以通过模拟方法实现,但是嘿,这个问题不受欢迎!
更新!
这可以通过挂接到 controllerSpy
method of IntegrationTestCase
来实现。这将允许您在 运行 测试之前将模拟模型附加到控制器。
例子:
/**
* @return void
*/
public function controllerSpy($event, $controller = null)
{
parent::controllerSpy($event, $controller);
if ($this->_controller) {
$usersMock = $this->getMockForModel('App\Model\Table\UsersTable', ['mailer'], [
'alias' => 'UsersTable',
'table' => 'users'
]);
$mailerMock = $this
->getMockBuilder('App\Mailer\UsersMailer')
->setMethods(['send'])
->getMock();
$usersMock
->method('mailer')
->will($this->returnValue($mailerMock));
$this->_controller->Users = $usersMock;
}
}
如果您将发送电子邮件的逻辑放入其自身的函数中,您应该能够执行如下操作:
$model = $this->getMockForModel('Users');
$model->expects($this->once())
->method('sendEmail')
->will($this->returnCallback(function ($user) {
$this->assertEquals(123, $user->id);
}));
我目前正在使用集成测试用例来测试某些端点上的响应,但不知道如何使用模拟方法来停止测试以及发送电子邮件等操作。
我的测试方法类似如下:
public function testInviteUser() {
$this->post('/invite-user', [
'name' => 'Joe Bloggs',
'email' => 'joe@bloggs.com'
]);
$this->assertRedirect([
'controller' => 'Users',
'action' => 'index'
]);
}
UsersTable
class 正在使用 Mailer
侦听 afterSave
事件并发送电子邮件。是否可以使用模拟对象来解决这个问题?我了解在其他地方进行单元测试时如何使用它们,但看不到文档中的示例如何适合集成测试。
没有找到方法来做到这一点,我使用了以下解决方案。
在名为 TESTING
的测试 bootstrap.php
中定义了一个常量,然后使用 defined('TESTING')
来确定是否应该发送电子邮件。不理想,因为我确定这可以通过模拟方法实现,但是嘿,这个问题不受欢迎!
更新!
这可以通过挂接到 controllerSpy
method of IntegrationTestCase
来实现。这将允许您在 运行 测试之前将模拟模型附加到控制器。
例子:
/**
* @return void
*/
public function controllerSpy($event, $controller = null)
{
parent::controllerSpy($event, $controller);
if ($this->_controller) {
$usersMock = $this->getMockForModel('App\Model\Table\UsersTable', ['mailer'], [
'alias' => 'UsersTable',
'table' => 'users'
]);
$mailerMock = $this
->getMockBuilder('App\Mailer\UsersMailer')
->setMethods(['send'])
->getMock();
$usersMock
->method('mailer')
->will($this->returnValue($mailerMock));
$this->_controller->Users = $usersMock;
}
}
如果您将发送电子邮件的逻辑放入其自身的函数中,您应该能够执行如下操作:
$model = $this->getMockForModel('Users');
$model->expects($this->once())
->method('sendEmail')
->will($this->returnCallback(function ($user) {
$this->assertEquals(123, $user->id);
}));