Макет объекта - Mock object

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

Мотивация

В модульный тест, фиктивные объекты могут моделировать поведение сложных реальных объектов и, следовательно, полезно, когда реальный объект непрактичен или невозможно включить в модульный тест. Если объект имеет любую из следующих характеристик, может быть полезно использовать вместо него фиктивный объект:

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

Например, программа-будильник, которая заставляет звонок звонить в определенное время, может получить текущее время от службы времени. Чтобы проверить это, тест должен дождаться времени будильника, чтобы узнать, правильно ли он прозвенел. Если служба фиктивного времени используется вместо службы реального времени, ее можно запрограммировать на обеспечение времени звонка (или любого другого времени) независимо от реального времени, так что программа будильника может быть протестирована изолированно.

Технические детали

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

Моки, подделки и заглушки

Классификация на моки, подделки и заглушки очень противоречиво в литературе.[1][2][3][4][5][6] Тем не менее, согласно литературным источникам, все они представляют собой производственный объект в среде тестирования, открывая один и тот же интерфейс.

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

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

В книге Искусство модульного тестирования[7] mocks описываются как поддельный объект, который помогает решить, не прошел ли тест, путем проверки того, произошло ли взаимодействие с объектом. Все остальное определяется как заглушка. В этой книге подделки все, что нереально, что, в зависимости от их использования, может быть заглушки или же издевается.

Установление ожиданий

Рассмотрим пример, в котором была имитирована подсистема авторизации. Мок-объект реализует isUserAllowed (задача: Задача): логическое[8] в соответствии с реальным классом авторизации. Если он также демонстрирует isAllowed: логическое недвижимость, которой нет в реальном классе. Это позволяет тестирующему коду легко установить ожидание того, что пользователю будет или не будет предоставлено разрешение при следующем вызове, и, следовательно, легко протестировать поведение остальной системы в любом случае.

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

Запись строк журнала

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

Это упущенная возможность. Мок-метод может добавить запись в строку общедоступного журнала. Запись должна быть не более чем «Человек сохранен»,[9]:146–7 или он может включать некоторые детали из экземпляра объекта person, такие как имя или идентификатор. Если тестовый код также проверяет окончательное содержимое строки журнала после различных серий операций с фиктивной базой данных, то можно проверить, что в каждом случае было выполнено точно ожидаемое количество сохранений базы данных. Это может найти в противном случае невидимые ошибки, снижающие производительность, например, когда разработчик, опасаясь потери данных, закодировал повторяющиеся вызовы спасти() где хватило бы только одного.

Использование в разработке через тестирование

Программисты, работающие с разработка через тестирование (TDD) используют фиктивные объекты при написании программного обеспечения. Мок-объекты соответствуют интерфейс требования и замена более сложных реальных требований; таким образом они позволяют программистам писать и модульный тест функциональность в одной области без вызова сложных базовых или совместной работы классы.[9]:144–5 Использование фиктивных объектов позволяет разработчикам сосредоточить свои тесты на поведении тестируемой системы, не беспокоясь о ее зависимостях. Например, тестирование сложного алгоритма, основанного на нескольких объектах, находящихся в определенных состояниях, может быть четко выражено с помощью фиктивных объектов вместо реальных.

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

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

Ограничения

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

Имитируемые объекты должны точно моделировать поведение объекта, который они издеваются, чего может быть трудно добиться, если объект, который подвергается издевательству, исходит от другого разработчика или проекта или если он еще даже не был написан. Если поведение не смоделировано правильно, то модульные тесты могут зарегистрировать прохождение, даже если сбой произойдет во время выполнения при тех же условиях, что и модульный тест, что делает модульный тест неточным.[10]

Смотрите также

Рекомендации

  1. ^ "Заглушки и макеты".
  2. ^ "отсталость: моки и заглушки не шпионы". 21 октября 2007 г.
  3. ^ "Моки, подделки, заглушки и манекены на XUnitPatterns.com".
  4. ^ "Какая разница между макетом и заглушкой?".
  5. ^ «В чем разница между притворством, издевательством и заглушкой?».
  6. ^ Перья, Майкл (2005). «Чувство и разделение». Эффективная работа с устаревшим кодом. Нью-Джерси: Прентис Холл. п. 23 и след. ISBN  0-13-117705-2.
  7. ^ Ошеров, Рой (2009). «Тестирование взаимодействия с фиктивными объектами и т.д.». Искусство модульного тестирования. Мэннинг. ISBN  978-1-933988-27-6.
  8. ^ В этих примерах используется номенклатура, аналогичная той, что используется в Единый язык моделирования
  9. ^ а б Бек, Кент (2003). Разработка через тестирование на примере. Бостон: Эддисон Уэсли. ISBN  0-321-14653-0.
  10. ^ InJava.com к издевательству | O'Reilly Media

внешняя ссылка