Чтобы построить ответ @ aib, когда мы начали модульное тестирование нашей унаследованной кодовой базы, большинство наших классов были очень тесно связаны, и многие методы сами создавали новые объекты. Хотя мы предприняли шаги по внедрению Dependency Injection и Inversion of Control в будущем, мы все еще застряли с сотнями классов, которые все еще нуждались в модульном тестировании.
При написании модульного теста для унаследованного метода мы провели рефакторинг и вытащили экземпляр в новый небольшой метод, который затем можно было бы заглушить. Не самая лучшая модель, но она была дешевой и выполняла работу без необходимости большого рефакторинга.
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 на основе конструктора, и я дам ответ, если вы создаете что-то новое. Вот ссылка, сделанная кем-то другим, потому что я уверен, что раньше было сказано лучше (вроде DRY): Внедрение зависимостей и модульное тестирование . И несколько примеров каждого для вашего случая:
Инжектор на основе конструктора
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));
}
}
Сеттер впрыска
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));
}
}