Инжектирование фиктивных объектов с использованием PHP-DI для тестирования контроллеров с помощью PHPUnit - PullRequest
0 голосов
/ 21 января 2019

Я реорганизовал некоторые из моих контроллеров для использования внедрения зависимостей через внедрение свойств , как рекомендовано в "передовых практиках" :

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.

1 Ответ

0 голосов
/ 22 января 2019

Может быть, есть специфический ответ для PHP-DI, но я не знаю, как с этим.Также кажется, что определение конструктора в вашем случае недопустимо.Учитывая это, вы можете использовать статический конструктор pretend для тестирования, который позволяет получить доступ к настройке внутреннего состояния:

<?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] => объект (B) # 1 (0) {}}

...