如何对 Symfony2 控制器进行单元测试?
我想尽可能多地使用测试驱动开发 - 这是一种很好的工作方式。
我对Symfony2控制器创建并返回一个新对象的事实感到不安。Response
我希望能够单独对控制器进行单元测试。
你是怎么做到的?
答案是将控制器创建为普通的旧PHP对象,将其注册为服务并使用依赖注入将新对象(或工厂)传递到其中?Response
Response
我想尽可能多地使用测试驱动开发 - 这是一种很好的工作方式。
我对Symfony2控制器创建并返回一个新对象的事实感到不安。Response
我希望能够单独对控制器进行单元测试。
你是怎么做到的?
答案是将控制器创建为普通的旧PHP对象,将其注册为服务并使用依赖注入将新对象(或工厂)传递到其中?Response
Response
通常,控制器将不同的对象插入在一起,并以正确的顺序连接它们。也许他调用了一个存储库,读取一些对象并通过渲染方法返回它们。也许他打电话给其他一些做事的处理者/经理。
这意味着控制器是高级组件。通常,这表示功能测试是有序的,而不是单元测试。您不应该以单元测试获得100%的代码覆盖率为目标。也许你可以这样想:如果你对控制器调用的所有内容(模型、验证、表单、存储库)进行单元测试,那么什么会出错?大多数时候,只有在生产中使用涉及的所有实际类时,您才能观察到它。
我还想指出,TDD并不意味着一切都必须进行单元测试。对高级代码进行一些功能测试是可以的。如前所述,如果您使用单元测试来测试低级组件,则只应测试它们如何协同工作,而您无法使用模拟进行测试,因为您告诉模拟的返回值是什么。
如果你的控制器不仅仅是将系统的各个部分插入在一起,你应该考虑将这些东西重构为更低级的类,你可以用单元测试进行测试。
因此,我的建议是使用功能测试来测试控制器,并使用单元测试来测试模型和业务逻辑内容。
如果您在功能测试中遇到困难,可以阅读以下内容:
使用模拟将模型和其他对象与主控制器方法的逻辑隔离开来,请参阅 http://www.phpunit.de/manual/3.7/en/test-doubles.html#test-doubles.mock-objects
我认为在旧版本中,你可以嘲笑整个类,但是对于我拥有的最新phpunit 3.6.10,它似乎不起作用。所以我猜你留下了堕落注入模式
class objss{
function ss(){
$x = new zz();
var_dump($x->z());
}
}
class MoTest extends PHPUnit_Framework_TestCase{
public function setUp(){
}
public function testA(){
$class = $this->getMock('zzMock', array('z'), array(), 'zz');
$class->expects($this->any())->method('z')->will($this->returnValue('2'));
$obj = new objss();
$this->assertEquals('2', $obj->ss());
}
}