在phpunit中__construct和setup之间有什么区别?

问题描述:

我很好奇知道在测试类__construct中创建对象或者我们应该总是使用setup/teardown方法(或setUpBeforeClass/tearDownAfterClass方法)是好的做法吗?在phpunit中__construct和setup之间有什么区别?

我意识到每个测试都会调用set/teardown,所以如果我把它的对象创建代码放进去,它会有什么用处?例如

//mytestclass.php

class MyTestClass extends PHPUnit_Framework_TestCase 
{ 

    private $obj; 

    protected function setUp() 
    { 
     $this->obj = new FooClass(); 

    } 

    public testFooObj() 
    { 
    //assertions for $this->obj 
    } 


    ... 

} 

可能是什么问题,如果我在构造函数创建对象是这样的:

class MyTestClass extends PHPUnit_Framework_TestCase 
    { 

     private $obj; 

     protected function __construct() 
     { 
      $this->obj = new FooClass(); 

     } 

     public testFooObj() 
     { 
     //assertions for $this->obj 
     } 


     ... 

    } 

我试着用搜索引擎周围以及PHPUnit文档无法得到关于的很多信息,你能帮我解开哪一个是好的做法吗?

setUp()在您的每个测试运行之前被调用。当你的类被实例化时发生__construct()。因此,如果您有多个测试并使用本地属性并对其进行修改,则可以使用setUp()确保在每次测试运行之前它们都是相同的。与setUp()相反的是tearDown(),您可以确保在每次测试后清理测试数据。

+0

感谢@ian,想如果我不改变的局部性质,只是读他们,那么哪一个更好? _construct或setUp?为每个测试用例创建对象不会添加一些开销? – Rahul 2014-10-07 12:41:12

+0

这取决于你的财产的性质和目的。如果他们提供测试数据,那么你应该使用'setUp()',如果他们提供了其他的东西(API url,一些环境标志,只读参数),那么你应该初始化它们,否则构造函数绝对是一个选项。使用'setUp()'在PHPUnit中事实上是用来配置每个测试的,你可以把它看作是在处理框架时的良好态度。当然可能会有开销,在这种情况下,您可以简单地检查属性是否已经设置,而不是重新初始化它。 – 2014-10-07 12:57:56

+0

或者,如果将它移动到构造函数中,将不会发生任何错误 - 只会因为不遵循标准而被诅咒;) – 2014-10-07 13:00:25

正如我刚才发现的那样,实现默认的类构造函数而不是setupBeforeClass()方法会打破@dataProvider注释(可能是所有类型的注释),对任何参数化测试都会产生“Missing argument”异常。

Missing argument 1 for AppBundle\Tests\Service\InvitationVerifierTest::testDireccionInvalida() 

public static function setUpBeforeClass()更换public function __construct()摆脱了异常。因此,它支持常规构造函数中的setupBeforeClass()方法。

PHPUnit的版本4.5.0

+0

我刚刚在PHPUnit 5.4.4中也看到了这种行为。 – darrenp 2016-07-13 17:18:56