Php 如何对Symfony2控制器进行单元测试?
我希望尽可能多地使用测试驱动开发——这是一种很好的工作方式 Symfony2控制器创建并返回一个新的Php 如何对Symfony2控制器进行单元测试?,php,unit-testing,symfony,Php,Unit Testing,Symfony,我希望尽可能多地使用测试驱动开发——这是一种很好的工作方式 Symfony2控制器创建并返回一个新的响应对象,这让我很困扰 我希望能够独立地对控制器进行单元测试 你是怎么做到的 将控制器创建为普通的旧PHP对象,将其注册为服务,并使用依赖项注入将新的响应对象(或响应工厂)传递到其中,这是解决方案吗?使用mock将模型和其他对象与主控制器方法的逻辑隔离,请参阅 我认为在旧版本中,您可以模拟整个类,但在我拥有的最新phpunit3.6.10中,它似乎不起作用。所以我猜你只剩下依赖注射模式了 clas
响应
对象,这让我很困扰
我希望能够独立地对控制器进行单元测试
你是怎么做到的
将控制器创建为普通的旧PHP对象,将其注册为服务,并使用依赖项注入将新的
响应
对象(或响应
工厂)传递到其中,这是解决方案吗?使用mock将模型和其他对象与主控制器方法的逻辑隔离,请参阅
我认为在旧版本中,您可以模拟整个类,但在我拥有的最新phpunit3.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());
}
}
通常,控制器将不同的对象插入到一起,并按正确的顺序连接它们。也许他调用一个存储库,读取一些对象,然后通过render方法返回它们。也许他会打电话给其他负责人/经理 这意味着控制器是一个高级组件。这通常表明功能测试是有序的,而不是单元测试。您的目标不应该是在单元测试中获得100%的代码覆盖率。也许您可以这样想:如果您对控制器调用的所有内容(模型、验证、表单、存储库)进行单元测试,会出现什么问题?大多数情况下,只有在使用生产中涉及的所有实际类时才能观察到这一点 我还想指出,TDD并不意味着一切都必须进行单元测试。可以对高级代码进行一些功能测试。如上所述,如果您使用单元测试测试低级组件,您应该只测试它们如何协同工作,而不能使用模拟测试,因为您告诉模拟返回值是什么 如果您的控制器所做的不仅仅是将系统的各个部分连接在一起,那么您应该考虑将这些内容重构成更低级的类,您可以使用单元测试进行测试 所以我的建议是使用功能测试来测试控制器,使用单元测试来测试模型和业务逻辑 如果您在功能测试中遇到困难,可以阅读以下内容:
- 刘易斯-我想我会跳到这里来。上述方法使您能够在测试中复制操作逻辑的更好部分。这并没有错,许多框架(尤其是Rails中的RSPEC)实际上建议您在控制器对象上执行单元测试和功能测试。然而,考虑到你的例子,我想我应该跳过单元测试,转而使用函数方法
在我看来,测试的目的是创建一个沙盒环境,运行测试,并检查副作用和直接结果。如果您的大部分测试都是隔离方法,那么可能是时候使用不同的测试方法或不同的方法来编写类了。考虑到这是一个控制器,并且它们自然地将堆栈的不同部分粘合在一起,我将创建堆栈上更远的沙箱。具体而言,我将使用如下方法:
对我来说效果很好:)单元测试
将控制器重构为服务:
然后您可以轻松地对它们进行单元测试
功能测试
当然(正如其他人已经提到的),您可以使用
WebTestCase
,如下所述:Totaly-但是这些对象(包括响应对象)将在控制器中实例化。除非我使用DI容器为控制器提供模型和其他东西。也许我可以创建一个响应工厂服务,并从DI容器中获取它-这样它(DI容器和工厂)就可以被模拟来单独测试控制器类。它返回响应对象到底有什么问题?什么都没有。我只是不喜欢在控制器中创建响应对象。我是依赖注入的坚定信徒,我讨厌在DI容器之外的任何东西中看到“new”关键字。也许这个信念是错误的,好吧。我认为,由于控制器是一个类,它也需要进行单元测试。我不喜欢在编写测试之前编写代码的想法,所以我想知道是否有一种方法可以重构控制器的使用方式,以便能够对其进行单元测试。我想我仍然可以通过在编写控制器之前编写功能测试来使用TDD。Symfony并不正式推荐将控制器定义为服务。一些开发人员将它们用于非常特定的用例,例如DDD(域驱动设计)和六边形体系结构应用程序。谁说的?在他们自己的文件中,赞成者多于反对者。我很确定在未来版本的symfony中将支持控制器作为服务,所以我不会太担心它“不是官方推荐的”。