насмешка — заставить метод PHP генерировать исключение в тесте

у меня есть AuthorizationUpdater сервис, с реализацией, основанной на Учение ОРМ. Когда я закончил рабочий код и провел несколько тестов, я был вынужден покинуть свой обычный цикл TDD, не зная, как написать эти два:

Доктрина реализации AuthorizationUpdater принять доктрину EntityManager в своем конструкторе, который он использует для чтения и записи. Предполагается, что эти два теста проверяют, когда один из этих методов EntityManager генерирует Doctine. ORMException, он перехватывается службой и преобразуется в исключение домена.

Мой тест является интеграционным тестом, который получает EntityManager использовать с завода.

Создание простой подделки через фиктивный API PHPUnit (getMock('className')->method('updateStuff')->willThrow(new SomeExcetion)не кажется хорошим в этом случае. Служба использует EntityManager перед тем, как метод выбрасывает исключение, так что макетировать все не вариант. Это оставляет создание сложной подделки EntityManager и частично издеваться над ним (просто метод, который должен вызвать исключение). Последнее требует предоставления реальных аргументов конструктора, к которым мой тест фактически не имеет доступа, так как эта ответственность лежит в другом пакете. Следовательно, оба подхода не являются удовлетворительными, и я предпочитаю иметь это ORMException поведение при ловле не проверяется.

Есть ли хороший способ написать тесты, которые мне нужны? Возможность обезьяны-исправления соответствующего метода на EntityManager экземпляр будет префектом, хотя это потребует расширение runkit.

Я использую PHP 7 и, возможно, смогу переключиться на PHP 7.1. Если вам интересно, код есть на GitHub, с соответствующими тестами, проживающими в конце DoctrineAuthorizationUpdaterTest.

2

Решение

Вместо создания фиктивного объекта через фиктивный API-интерфейс PHPUnit вы можете создать прокси-класс в своем тестовом пространстве имен, который получит EntityManager с завода в качестве параметра конструктора. Прокси-класс передает каждый вызов метода EntityManagerкроме звонков, которые должны вызвать исключение. Большинство вызовов может быть передано с помощью __call магический метод, за исключением вызовов интерфейсных методов Doctrine\Common\Persistence\ObjectManager, который, вероятно, придется реализовать классу Proxy (методы интерфейса не могут быть реализованы с call).

Является ли этот прокси-класс «сложной подделкой», о которой вы говорите и хотите избежать? Тогда, может быть, вы можете использовать Библиотека издевательств и не нужно писать класс.

1

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]