Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/unit-testing/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Unit testing PHP中的单元测试控制器-我应该模拟所有东西吗?_Unit Testing_Mocking_Zend Framework2 - Fatal编程技术网

Unit testing PHP中的单元测试控制器-我应该模拟所有东西吗?

Unit testing PHP中的单元测试控制器-我应该模拟所有东西吗?,unit-testing,mocking,zend-framework2,Unit Testing,Mocking,Zend Framework2,基本上,我有一个用Zend Framework 2编写的应用程序。 我的控制器经过了很好的测试,当我体验到这一点时,我问自己: “我应该嘲弄我能嘲弄的一切吗?” 例如: public function someAction() { $form = new SomeForm(); if ($this->getRequest()->isPost()) { $form->setData($this->getRequest()->getPos

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

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

例如:

public function someAction()
{
    $form = new SomeForm();
    if ($this->getRequest()->isPost()) {
        $form->setData($this->getRequest()->getPost());
        if ($form->isValid()) {
            doSomething();
        }
    }
}
现在:我应该嘲笑表单吗?我学会了尽可能多的嘲弄。
另一方面,我读到有一种叫做“过度嘲弄”的东西,它的基本意思是,如果你嘲弄太多,那就不好了,因为考试可能会被打破。

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

我应该嘲笑一切吗?

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

如何测试此控制器操作?

在您的示例中,根据我的第一个答案,我只会“模拟”请求对象,即使在这种情况下,我也不会真正进行模拟(在使用
getMock(…)
事物的意义上),我只会手动构造
请求
对象。抱歉,如果这在语法上不正确,我会把它从我的头上写下来:

$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”方法(如果您想验证是否调用了该方法)。

我不会对控制器进行单元测试。单元测试具有类似服务的业务逻辑的模型和类。您可以使用BDD(Behat)测试应用程序端到端的流。这样,您就不会模仿任何东西,而是正确地测试控制器。您可以使用不同的驱动程序进行测试:headless-like Goutte(适用于没有JS的页面)或支持JavaScript的驱动程序,用于JS重页面,例如Selenium 2或Zombie driver。BDD不限制您一次测试一个控制器动作,而是允许您在网站上测试特定功能的整个流程,这可能包括几个控制器动作以及它们之间的交互。例如,您可以编写一个BDD场景来测试注册流。此BDD将首先打开带有注册表的页面,填写字段,提交表单,检查您是否收到激活电子邮件(要检查电子邮件,我将在我的CI服务器上记录所有发送的电子邮件,所以我只需检查电子邮件日志),转到激活链接,然后转到登录页面。。。