在控制器中对模拟对象使用期望的最佳实践是什么
What is the best practice to use expectations on mocked objects in controllers
我经常想在控制器中模拟出一个组件或对象。我使用 controllerSpy 方法来执行此操作:
public function controllerSpy($event, $controller = null)
{
parent::controllerSpy($event, $controller);
$OrderConfirmation = $this->getMockBuilder('OrderConfirmation')
->setMethods(['send'])
->getMock();
$OrderConfirmation->expects($this->once())->method('send');
$this->_controller->OrderConfirmation = $OrderConfirmation;
}
问题是在每次测试中都设置了调用 send-Method 的预期。但是要看场景,也有不发送确认的场景。我想在测试本身而不是在 controllerSpy
方法中全局配置期望。像这样:
public function testAddOrder()
{
$this->_controller->OrderConfirmation->expects($this->once())->method('send');
$this->post('/add_order');
}
但她的问题是预期会丢失,因为稍后会覆盖整个 OrderConfirmation 对象。有人解决过这个问题吗?
您可以只收听 Controller.initialize
事件,这也是测试调度程序所做的:
public function testAddOrder()
{
\Cake\Event\EventManager::instance()->on(
'Controller.initialize',
function (\Cake\Event\EventInterface $event) {
/** @var \Cake\Controller\Controller $controller */
$controller = $event->getSubject();
// ...
$controller->OrderConfirmation = $OrderConfirmation;
}
);
$this->post('/add_order');
}
或者为 controllerSpy()
方法实现回调,例如:
protected $controllerSpyCallback;
public function controllerSpy($event, $controller = null)
{
parent::controllerSpy($event, $controller);
if (is_callable($this->controllerSpyCallback)) {
$this->controllerSpyCallback($this->_controller);
}
}
public function testAddOrder()
{
$this->controllerSpyCallback = function (\Cake\Controller\Controller $controller) {
// ...
$controller->OrderConfirmation = $OrderConfirmation;
};
$this->post('/add_order');
}
我经常想在控制器中模拟出一个组件或对象。我使用 controllerSpy 方法来执行此操作:
public function controllerSpy($event, $controller = null)
{
parent::controllerSpy($event, $controller);
$OrderConfirmation = $this->getMockBuilder('OrderConfirmation')
->setMethods(['send'])
->getMock();
$OrderConfirmation->expects($this->once())->method('send');
$this->_controller->OrderConfirmation = $OrderConfirmation;
}
问题是在每次测试中都设置了调用 send-Method 的预期。但是要看场景,也有不发送确认的场景。我想在测试本身而不是在 controllerSpy
方法中全局配置期望。像这样:
public function testAddOrder()
{
$this->_controller->OrderConfirmation->expects($this->once())->method('send');
$this->post('/add_order');
}
但她的问题是预期会丢失,因为稍后会覆盖整个 OrderConfirmation 对象。有人解决过这个问题吗?
您可以只收听 Controller.initialize
事件,这也是测试调度程序所做的:
public function testAddOrder()
{
\Cake\Event\EventManager::instance()->on(
'Controller.initialize',
function (\Cake\Event\EventInterface $event) {
/** @var \Cake\Controller\Controller $controller */
$controller = $event->getSubject();
// ...
$controller->OrderConfirmation = $OrderConfirmation;
}
);
$this->post('/add_order');
}
或者为 controllerSpy()
方法实现回调,例如:
protected $controllerSpyCallback;
public function controllerSpy($event, $controller = null)
{
parent::controllerSpy($event, $controller);
if (is_callable($this->controllerSpyCallback)) {
$this->controllerSpyCallback($this->_controller);
}
}
public function testAddOrder()
{
$this->controllerSpyCallback = function (\Cake\Controller\Controller $controller) {
// ...
$controller->OrderConfirmation = $OrderConfirmation;
};
$this->post('/add_order');
}