1

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

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

例如:

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

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

4

1 回答 1

0

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

我应该嘲笑一切吗?

一般来说,您应该尽可能少地模拟来测试功能。如果你尽可能多地模拟,你永远不会真正看到你的方法是如何相互交互的(不是integration,因为集成测试是一个独特的概念)。

我应该如何测试这个控制器动作?

在您的示例中,根据我的第一个答案,我只会“模拟”请求对象,即使在这种情况下,我实际上也不会进行模拟(在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”方法(如果您想验证它是否被调用)。

于 2013-08-06T13:35:33.703 回答