Я реорганизовал некоторые из своих контроллеров, чтобы использовать внедрение зависимостей через внедрение свойств как рекомендовано в "лучших практиках":
final class ZebraController extends Controller
{
/**
* @Inject
* @var AnimalClientInterface
*/
private $animalsRestClient;
public function fetchAllZebras(ServerRequestInterface $req): ResponseInterface {
// ...
}
}
Моя конфигурация PHP-DI настроена на внедрение экземпляра объекта AnimalClient для AnimalClientInterface, что хорошо в коде реализации, поскольку существует только 1 настоящий AnimalClient.
В моем модульном тесте мне нужно внедрить MockZebraClient в это свойство. Я не могу просто настроить его, как я делаю это для AnimalClient, потому что другие классы могут быть аннотированы аналогичным образом, но им нужен, например, MockTigerClient для тестирования.
Это мой модульный тест:
class ZebraControllerTest extends TestCase
{
/** @var ZebraController */
protected $object;
public function testFetchAllZebras(): void {
// assertions here
}
}
Я думаю, что использование Метод injectOn — правильный способ решить эту проблему, но я не знаю, как настроить контейнер, чтобы выбрать правильный фиктивный объект для правильного теста.
Внедрение конструктора невозможно из-за устаревшей структуры кода. Все контроллеры в приложении должны быть реорганизованы для использования DI, чтобы изменить конструктор Controller.
@ДжонВ. К сожалению, я не могу изменить сигнатуру метода конструктора Controller из-за устаревшей структуры кода. Переопределение его в дочернем классе для добавления дополнительных параметров также невозможно, пока все контроллеры в кодовой базе не будут реорганизованы для использования DI.






Возможно, есть конкретный ответ PHP-DI, но я с ним не знаком. Также кажется, что определение конструктора не разрешено в вашем случае. Учитывая это, вы можете использовать статический конструктор для тестирования, который позволяет получить доступ к настройке внутреннего состояния:
<?php
class A {
private $b;
public static function construct($b) {
$a = new A();
$a->b = $b;
return $a;
}
}
class B {
}
$a = A::construct(new B());
var_dump($a);
Возвращает:
object(A)#2 (1) { ["b":"A":private]=> object(B)#1 (0) { } }
Не знаком с PHP-DI, но вы всегда можете добавить конструктор и вызвать его в своих тестах.