Я новичок в модульном тестировании и PHPUnit, но в последнее время я много читал о шаблонах проектирования и изолированных тестах, и я решил провести рефакторинг приложения, которое я Я работаю над тем, чтобы избавиться от статических классов, синглетонов, жестко закодированных зависимостей и всего остального, определенного в глобальной области видимости, надеюсь, что это станет «тестируемым», а не занозой в заднице в будущем, поскольку это должно быть долгосрочный проект.
До сих пор я полагал, что понимаю теорию модульного тестирования, но мне было интересно, в сценарии, когда кто-то делегирует обработку вложенных зависимостей объектов Фабрике, как следует проводить модульное тестирование указанной Фабрики, или это просто избыточно? проверить это? И как лучше всего проверить, что «цепочка» зависимостей работает синхронно?
Позвольте мне проиллюстрировать вопросы. Предположим, у вас есть следующий «устаревший» код:
class House {
protected $material;
protected $door;
protected $knob;
public function __construct() {
$this->door = new Door();
$this->knob = $this->door->getKnob();
$this->material = "stone";
echo "House material: ".$this->material. PHP_EOL. "<br/>";
echo "Door material: ".$this->door->getMaterial(). PHP_EOL. "<br/>";
echo "Knob material: ".$this->knob->getMaterial(). PHP_EOL. "<br/>";
}
}
class Door {
protected $material;
protected $knob;
public function __construct() {
$this->knob = new Knob();
$this->material = "wood";
}
public function getKnob() {
return $this->knob;
}
public function getMaterial () {
return $this->material;
}
}
class Knob {
protected $material;
public function __construct() {
$this->material = "metal";
}
public function getMaterial () {
return $this->material;
}
}
$house = new House();
Это (насколько я понимаю)плохо подходит для модульного тестирования, поэтому мы заменяем жестко заданные зависимости на DI + класс Factory:
class House {
protected $material;
protected $door;
protected $knob;
public function __construct($door) {
$this->door = $door;
$this->knob = $this->door->getKnob();
$this->material = "stone";
echo "House material: ".$this->material. PHP_EOL. "<br/>";
echo "Door material: ".$this->door->getMaterial(). PHP_EOL. "<br/>";
echo "Knob material: ".$this->knob->getMaterial(). PHP_EOL. "<br/>";
}
}
class Door {
protected $material;
protected $knob;
public function __construct($knob) {
$this->knob = $knob;
$this->material = "wood";
}
public function getKnob() {
return $this->knob;
}
public function getMaterial () {
return $this->material;
}
}
class Knob {
protected $material;
public function __construct() {
$this->material = "metal";
}
public function getMaterial () {
return $this->material;
}
}
class HouseFactory {
public function create() {
$knob = new Knob();
$door = new Door($knob);
$house = new House($door);
return $house;
}
}
$houseFactory = new HouseFactory();
$house = $houseFactory->create();
Теперь (и опять же, насколько я понимаю,)House, Door и Knob можно прекрасно протестировать с помощью фиктивных зависимостей. Но:
1)Что теперь происходит с HouseFactory?
Следует ли просто:
2)Можно ли настроить тесты, основанные на нескольких (не имитируемых)зависимостях одновременно? Я понимаю, что технически это не модульное тестирование, (возможно, интеграционное тестирование? ), но я думаю, что это все еще вполне выполнимо с использованием PHPUnit? Учитывая приведенный выше пример, я хотел бы иметь возможность настроить тест, который не только проверяет House, Door, Knob и HouseFactory изолированно, но и результаты взаимодействия реальных объектов друг с другом, возможно, с некоторыми их имитируемые функции, например те, которые имеют дело с данными. Является ли PHPUnit плохим выбором для такого рода тестов?
Заранее спасибо за внимание. Я понимаю, что некоторые из моих предположений могут быть неверны, поскольку я, очевидно, не эксперт в этом вопросе; исправления приветствуются и приветствуются.