Я пишу юнит-тесты для тестирования API, который в настоящее время находится в стадии разработки. У меня есть класс контейнера-макета (шаблон декоратора), который содержит массив макетов, которые будут выполняться вместо вызовов реальных объектов.
Эти фиктивные контейнеры помещаются в DI-контейнер во время тестового прогона, и вызовы попадают в контейнер вместо модели / контроллеров. В большинстве случаев мы пропускаем функции контроллеров, но иногда нам хочется их высмеять. Контейнер-макет работает, перехватывая недоступные вызовы функций через __call
и либо возвращение назначенных имитационных данных, либо попадание во внутренний объект.
Это прекрасно работает в случае использования:
$this->c['Controller_Name']->functionHere()
Как c['Controller_Name']
является экземпляром нашего фиктивного контейнера, но проблема с этим подходом исходит от контроллера, ссылающегося на себя через $this->functionHere()
когда functionHere
надо издеваться, но звонок происходит на $this
который является экземпляром контроллера, а не нашего ложного контейнера.
Есть ли правдоподобный метод для перехвата вызовов классов собственных членов, так что я могу поймать $this->functionHere()
и перевести его соответствующим образом в $this->c['Controller_Name']->functionHere()
Не зная ваших настроек, сложно говорить о специфике, но поскольку вы используете Dependency Injection, то обеспечение того, что вы будете взаимодействовать с любыми реализациями, которые вы хотите исключить из тестирования, будет означать, что вы можете создавать фиктивные версии, сопоставленные, например, с помощью отдельного TestDIModule. Таким образом, вам не нужно ничего перехватывать.
Что касается перехвата вызовов функций внутри объекта — я бы предположил, что если вам нужно это сделать, это может указывать на то, что ваш класс выполняет несколько «единиц» работы, поэтому может быть реорганизован в отдельные классы и связать их. Извлечение их в интерфейсы, как описано выше, позволило бы их смоделировать и протестировать независимо.
Других решений пока нет …