Unit testing PHP中的单元测试控制器-我应该模拟所有东西吗?
基本上,我有一个用Zend Framework 2编写的应用程序。 我的控制器经过了很好的测试,当我体验到这一点时,我问自己: “我应该嘲弄我能嘲弄的一切吗?” 例如: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
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服务器上记录所有发送的电子邮件,所以我只需检查电子邮件日志),转到激活链接,然后转到登录页面。。。