我是一个单元测试初学者,似乎陷入了如何对包含内部函数调用的函数进行单元测试的困境。例如,测试以下内容:
public function getBlueFooCount($fooId) {
$foo = $fooDao->getFoosById($fooId);
// custom logic to pull out the blue foos from result set
// custom count business logic on blue foos ...
return $count;
}
我如何能够模拟内部函数检索的内容?这是因为功能耦合太紧,需要放松一下吗?
最佳答案
为了构建@aib的答案,当我们开始对遗留代码库进行单元测试时,我们的大多数类都非常紧密地耦合,并且许多方法本身正在实例化新对象。虽然我们已采取措施实现 Dependency Injection和 Inversion of Control展望 future ,我们仍然受制于数百个仍需要单元测试的类。
在为遗留方法编写单元测试时,我们重构并将实例化为一个新的小方法,然后我们可以 stub 。不是最好的模式,但它很便宜并且无需进行更大的重构即可完成工作。
class FooCounter {
public function getFooDao(){
return new FooDao();
}
public function getBlueFooCount($fooId) {
/* was this
$fooDao = new FooDao();
*/
$foo = $this->getFooDao()->getFoosById($fooId);
// custom logic to pull out the blue foos from result set
// custom count business logic on blue foos ...
return $count;
}
}
class FooCounterTest extends PHPUnit_Framework_TestCase {
public function test_getBlueFooCount(){
$fooCounter = $this->getMock('FooCounter', array('getFooDao'));
$fooCounter->expects($this->any())
->method('getFooDao')
->will($this->returnValue(new MockFooDao()));
$this->assertEquals(0, $fooCounter->getBlueFooCount(1));
}
}
如果我们要实现一个新类,我们通常会使用基于构造函数的 DI,如果您要创建新的东西,这就是我将给出的答案。这是其他人的链接,因为我相信之前已经说过更好了(有点干):Dependency Injection and Unit Testing 。以及每个案例的一些示例:
基于构造函数的注入(inject)
class FooCounter {
private $_fooDao
public function __construct($fooDao){
$this->_fooDao = $fooDao
}
public function getBlueFooCount($fooId) {
$foo = $this->_fooDao->getFoosById($fooId);
// custom logic to pull out the blue foos from result set
// custom count business logic on blue foos ...
return $count;
}
}
class FooCounterTest extends PHPUnit_Framework_TestCase {
public function test_getBlueFooCount(){
$fooCounter = new FooCounter(new MockFooDao());
$this->assertEquals(0, $fooCounter->getBlueFooCount(1));
}
}
基于 Setter 的注入(inject)
class FooCounter {
private $_fooDao
public function setFooDao($fooDao){
$this->_fooDao = $fooDao
}
public function getBlueFooCount($fooId) {
$foo = $this->_fooDao->getFoosById($fooId);
// custom logic to pull out the blue foos from result set
// custom count business logic on blue foos ...
return $count;
}
}
class FooCounterTest extends PHPUnit_Framework_TestCase {
public function test_getBlueFooCount(){
$fooCounter = new FooCounter();
$fooCounter->setFooDao(new MockFooDao());
$this->assertEquals(0, $fooCounter->getBlueFooCount(1));
}
}
关于php - 测试具有内部函数调用的函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5761454/