如何对 Symfony2 控制器进行单元测试?

2022-08-30 14:33:38

我想尽可能多地使用测试驱动开发 - 这是一种很好的工作方式。

我对Symfony2控制器创建并返回一个新对象的事实感到不安。Response

我希望能够单独对控制器进行单元测试。

你是怎么做到的?

答案是将控制器创建为普通的旧PHP对象,将其注册为服务并使用依赖注入将新对象(或工厂)传递到其中?ResponseResponse


答案 1

通常,控制器将不同的对象插入在一起,并以正确的顺序连接它们。也许他调用了一个存储库,读取一些对象并通过渲染方法返回它们。也许他打电话给其他一些做事的处理者/经理。

这意味着控制器是高级组件。通常,这表示功能测试是有序的,而不是单元测试。您不应该以单元测试获得100%的代码覆盖率为目标。也许你可以这样想:如果你对控制器调用的所有内容(模型、验证、表单、存储库)进行单元测试,那么什么会出错?大多数时候,只有在生产中使用涉及的所有实际类时,您才能观察到它。

我还想指出,TDD并不意味着一切都必须进行单元测试。对高级代码进行一些功能测试是可以的。如前所述,如果您使用单元测试来测试低级组件,则只应测试它们如何协同工作,而您无法使用模拟进行测试,因为您告诉模拟的返回值是什么。

如果你的控制器不仅仅是将系统的各个部分插入在一起,你应该考虑将这些东西重构为更低级的类,你可以用单元测试进行测试。

因此,我的建议是使用功能测试来测试控制器,并使用单元测试来测试模型和业务逻辑内容。

如果您在功能测试中遇到困难,可以阅读以下内容:


答案 2

使用模拟将模型和其他对象与主控制器方法的逻辑隔离开来,请参阅 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());
    }
}

推荐