2009-09-15 48 views
2

虽然试图获得被测遗留代码库的构造函数依赖,我遇到一个对象,执行以下操作:删除使用PHPUnit的

class Foo 
{ 
    public function __construct($someargs) 
    { 
     $this->bar = new Bar(); 
     // [lots more code] 
    } 
} 

酒吧在这种情况下有一个构造函数,做一些坏事例如连接到数据库。我试图专注于测试得到这个Foo类,因此改成这样的:

class Foo 
{ 
    public function __construct($someargs) 
    { 
     $this->bar = $this->getBarInstance(); 
     // [lots more code] 
    } 

    protected function getBarInstance() 
    { 
     return new Bar(); 
    } 
} 

,并试图通过以下PHPUnit的测试,以测试它:

class FooTest extends PHPUnit_Framework_TestCase 
{ 
    public function testInstance() 
    { 

     $bar = $this->getMock('Bar'); 
     $foo = $this->getMock('Foo', array('getBarInstance')); 
     $foo->expects($this->any()) 
      ->method('getBarInstance') 
      ->will($this->returnValue($bar)); 

    } 

} 

然而这并未不工作--Foo()的构造函数在添加my - > expects()之前调用,所以模拟的getBarInstance()方法返回null。

有什么办法可以解除这种依赖关系而不必重构类使用构造函数的方式吗?

回答

4

使用$callOriginalConstructor参数getMock()。将其设置为false。这是该方法的第五个参数。看看这里:http://www.phpunit.de/manual/current/en/api.html#api.testcase.tables.api

其实,坚持下去。你想通过模拟来模拟?如果你真的想要这个,那么使用代表构造函数参数的第三个参数getMock。在那里,您可以将Bar的模拟传递给Foo的模拟。

+0

但构造函数确实'东西',应该分裂成一个单独的方法吗? – 2009-09-15 15:10:46

+0

我刚刚编辑了答案。你可以通过一个模拟模拟,但我真的不明白这一点。 – 2009-09-15 15:11:47

+0

是的,如果构造函数做的东西,你应该将该代码移动到一个单独的方法。构造函数通常应该设置对象的状态,例如将实例字段设置为特定值,通常作为参数传递给构造函数。 – 2009-09-15 15:12:58