cakephp 在控制器中对模拟对象使用期望值的最佳实践是什么

p5fdfcr1  于 2022-11-12  发布在  PHP
关注(0)|答案(1)|浏览(88)

我经常想模拟控制器中的组件或对象。我使用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对象稍后会被覆盖。以前有人解决过这个问题吗?

gfttwv5a

gfttwv5a1#

您可以只监听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');
}

相关问题