PHP中的单元测试控制器 - 我应该模拟一切吗?

时间:2013-06-02 16:07:59

标签: unit-testing mocking zend-framework2

基本上,我有一个用Zend Framework 2编写的应用程序。 我的控制器经过了相当好的测试,在我实现这一经验时,我问自己:

“我应该嘲笑我可以嘲笑的一切吗?”

例如:

public function someAction()
{
    $form = new SomeForm();
    if ($this->getRequest()->isPost()) {
        $form->setData($this->getRequest()->getPost());
        if ($form->isValid()) {
            doSomething();
        }
    }
}

现在:我应该嘲笑表格吗?我尽可能地学会了最好的模拟。 另一方面,我读到有一种叫做“过度模仿”的东西,这基本上意味着,如果你嘲笑太多,那就太糟糕了,因为测试可能会被打破。

1 个答案:

答案 0 :(得分:0)

我想你在这里已经提出了两个不同的问题,所以我会尝试回答它们。

我应该嘲笑一切吗?

通常,您应该尽可能少地模拟 来测试功能。如果你尽可能地模拟,你就不会真正看到你的方法如何相互作用(不是集成,因为集成测试是一个独特的概念)。

我该如何测试此控制器操作?

在你的例子中,并且与我的第一个答案一致,我只会“模拟”请求对象,即使在这种情况下,我也不会实际模拟(在使用getMock(..)的意义上事情),我只是手动构建一个Request对象。如果这在语法上不正确,我会道歉:我正在写下这个:

$request = new \Zend\Http\Request();
$request->setPost(new Parameters([/* array with whatever parameters your form might need */]));
$request->setMethod('POST');

$controller = new YourController();
$controller->setRequest($request); // you may need to use a \ReflectionProperty to do this
$controller->someAction();

我会使用数据提供程序创建POST参数来测试各种不同的输入,以检查您希望发生的事情将会发生

如果通过调用doSomething()会发生某些不良影响,那么如果您嘲笑该方法可能会有所帮助。因为doSomething()似乎只是一个函数而不是类方法,所以您可能需要一些不同的代码。但是,为简单起见,让我们调整您的初始示例以调用$this->doSomething(),我们的测试将更改为以下内容:

// set up $request as before

$controller = $this->getMock('\Your\Vendor\Controller\YourController', ['doSomething']);
$controller->expects($this->once())->method('doSomething');
$controller->setRequest($request); // you may need to use a \ReflectionProperty to do this
$controller->someAction();

这断言调用了“doSomething”方法(如果你想验证它是否被调用)。