Как интерфейсы упрощают модульное тестирование и насмешливость?

Часто говорят, что интерфейсы делают насмешливое и модульное тестирование более легким процессом. Как с этим справляются интерфейсы?

Ответ 1

Это характер интерфейсов обеспечивает множество реализаций, таким образом, позволяет насмехаться.

В частности, при тестировании интеграции вы можете предоставить свою версию макета системы зависимостей (например, веб-сервис). Вместо фактического вызова зависимой системы или даже модуля или сложного и сложного для создания типа вы можете предоставить простейшую реализацию интерфейса, которая предоставит необходимые результаты для unit test для правильной.

В дополнение к этому , когда вы используете при модульном тестировании, фактический зависимый тип (назовите его BigGraph), скрывая за собой сложную объектную модель, вы на самом деле интеграционное тестирование, а не модульное тестирование. Тестовый тест можно легко сломать, если есть ошибка в любом из зависимых типов (BigGraph), а не в том типе, который вы тестируете, а не в модульном тестировании. Использование макетов уменьшает риск этого.

Я видел много систем непрерывной интеграции, показывающих десятки ошибок для одной ошибки, когда они должны отображать одну или, самое большее, пару, из-за слишком сложных объектных моделей и неправильно написанного модульного теста - не используя mock -ups.

Сегодня издевательские фреймворки более сложны (модификация байт-кода и т.д.), чем старые, поэтому иногда интерфейсы или даже виртуальные методы не всегда нужны, но их поддерживают безжизненные интерфейсы.

Интерфейсы не помогут, если ваша объектная модель слишком сложна и захламлена (например, ваш интерфейс в значительной степени зависит от других типов/интерфейсов); то реализация/издевательство над этим - это боль.

Ответ 2

Если у вас есть несколько объектов, которые имеют другую реализацию, но предлагают одни и те же методы для совместного использования сторонними интерфейсами, вы можете написать один unit test и запустить его во всех реализациях.

Если у вас есть класс, в котором говорится о материалах сообщений на веб-конце, а затем извлекается тестирование единицы ответа, что было бы проблематично, потому что неудавшееся интернет-соединение могло позволить вашему тесту выйти из строя. Поэтому вы определяете интерфейс для этого класса, а затем можете написать вторую реализацию, которая регистрирует материал, который должен быть отправлен, и доставляет правильный ответ. Таким образом, вы можете протестировать классы, которые работают с ответом с обратной стороны, не полагаясь на подключение к Интернету во время тестового запуска.

Ответ 3

Если у вас есть класс, у вас может быть множество зависимостей, например

  • Конструкторы insane (много аргументов или нужны некоторые другие классы, которым нужен третий класс, которому нужен четвертый класс, который должен иметь действительное соединение с базой данных)

  • Чтобы использовать класс каким-либо образом, вы должны его инициализировать правильно (например, вы должны передать ему и другие объекты, которые также должны быть действительными)

  • Класс имеет состояние. По какой-либо причине это состояние может измениться во время теста.

  • Класс может иметь или использовать статические поля

Эти зависимости обычно неактуальны во время многих ваших тестов, и вам больше не придется иметь дело с ними.

С помощью интерфейса вы можете создать простой класс mock, который просто реализует несколько методов, которые вам нужны. У большинства насмешливых фреймворков есть встроенная поддержка для этого. "Реализация" здесь обычно означает "вернуть фиксированное значение". Таким образом, вы можете быстро создать среду, в которой нуждается тестируемый класс.

Так, например, если вашему классу нужно читать записи из базы данных, вы можете вместо этого выкрикнуть ResultSet, который просто возвращает строки. Следовательно, вам не нужно иметь реальную базу данных, вам не нужно создавать соединение (которое медленно и может не работать по многим причинам), вам не нужно заботиться о данных в базе данных (так что вы не 't нужно удалить/удалить таблицы и снова заполнить их тестовыми данными) и т.д.

Ответ 4

Если вы не привязаны к конкретной реализации, вы можете переключать поведение за интерфейсом.

Если ваши классы реализуют интерфейсы, поведение можно издеваться.

Например, вам не нужно спамить всех своих клиентов в своей базе данных, чтобы проверить, работает ли ваш алгоритм уведомления по электронной почте. Вы создадите макет для вашего интерфейса IMailSender и будете только подсчитывать количество отправленных сообщений электронной почты. Затем вы проверите фактическую реализацию, которая фактически отправит электронные письма на один адрес электронной почты, и вы знаете, что работает весь процесс уведомления.

В этом конкретном примере в тесте используется mock-реализация IMailSender, которая учитывает только отправленные сообщения и ваш фактический производственный код будет использовать реализацию реализации IMailSender, которая фактически отправляет электронные письма через SMTP-сервер.

Ответ 5

При тестировании поведения, пересекающего порт, наличие интерфейса для адаптера поможет внедрить другую реализацию во время тестирования (например, test double).

Например, DAO, который вызывает базу данных или веб-службу, может быть заменен реализацией, которая возвращает зашифрованные данные.