В объектно-ориентированном программировании , фиктивные объекты моделируются объекты , которые имитируют поведение реальных объектов в контролируемых способах, чаще всего , как часть программного обеспечения тестирования инициативы. Программист обычно создает фиктивный объект, чтобы проверить поведение какого-либо другого объекта, во многом так же, как конструктор автомобилей использует манекен для краш-тестов для имитации динамического поведения человека при столкновении с транспортным средством. Этот метод также применим в универсальном программировании .
Мотивация
В модульном тесте имитирующие объекты могут имитировать поведение сложных реальных объектов и поэтому полезны, когда реальный объект непрактичен или невозможно включить в модульный тест. Если объект имеет любую из следующих характеристик, может быть полезно использовать вместо него фиктивный объект:
- объект предоставляет недетерминированные результаты (например, текущее время или текущую температуру);
- в нем есть состояния, которые сложно создать или воспроизвести (например, сетевая ошибка);
- он медленный (например, полная база данных , которая должна быть инициализирована перед тестом);
- он еще не существует или может изменить поведение;
- он должен включать информацию и методы исключительно для целей тестирования (а не для своей реальной задачи).
Например, программа-будильник, которая заставляет звонить в определенное время, может получить текущее время от службы времени. Чтобы проверить это, тест должен дождаться времени будильника, чтобы узнать, правильно ли он прозвенел. Если служба фиктивного времени используется вместо службы реального времени, ее можно запрограммировать на обеспечение времени звонка (или любого другого времени) независимо от реального времени, так что программа будильника может быть протестирована изолированно.
Технические подробности
У имитационных объектов тот же интерфейс, что и у реальных объектов, которые они имитируют, что позволяет клиентскому объекту не знать, использует ли он реальный объект или фиктивный объект. Многие доступные фреймворки фиктивных объектов позволяют программисту указать, какие и в каком порядке методы будут вызываться для фиктивного объекта и какие параметры будут им переданы, а также какие значения будут возвращены. Таким образом, поведение сложного объекта, такого как сетевой сокет, может имитироваться фиктивным объектом, позволяя программисту обнаружить, реагирует ли тестируемый объект надлежащим образом на большое разнообразие состояний, в которых могут находиться такие фиктивные объекты.
Моки, подделки и заглушки
Классификация имитаторов, подделок и заглушек очень противоречива в литературе. [1] [2] [3] [4] [5] [6] Тем не менее, согласно литературным источникам, все они представляют производственный объект в среде тестирования, открывая один и тот же интерфейс.
Что из имитации , подделки или заглушки является самым простым, непоследовательно, но самый простой всегда возвращает заранее подготовленные ответы (как в случае заглушки метода ). С другой стороны, наиболее сложный объект будет полностью имитировать производственный объект с полной логикой, исключениями и т. Д. Подходит ли какое-либо трио имитация, подделка или заглушка такому определению, опять же, непоследовательно во всем литература.
Например, реализация имитационного, поддельного или заглушенного метода между двумя концами спектра сложности может содержать утверждения для проверки контекста каждого вызова. Например, фиктивный объект может утверждать порядок, в котором вызываются его методы, или утверждать согласованность данных между вызовами методов.
В книге «Искусство модульного тестирования» [7] моки описываются как фальшивый объект, который помогает решить, не прошел ли тест или был пройден, путем проверки того, произошло ли взаимодействие с объектом. Все остальное определяется как заглушка. В этой книге под фейками понимается все, что не является настоящим, что в зависимости от их использования может быть либо заглушкой, либо имитацией .
Установление ожиданий
Рассмотрим пример, в котором была имитирована подсистема авторизации. Мок-объект реализует метод isUserAllowed(task : Task) : boolean
[8], соответствующий методу реального класса авторизации. Если он также предоставляет isAllowed : boolean
свойство, которого нет в реальном классе, это дает много преимуществ . Это позволяет коду тестирования легко установить ожидание того, что пользователю будет или не будет предоставлено разрешение при следующем вызове, и, следовательно, легко протестировать поведение остальной системы в любом случае.
Аналогичным образом, фиктивные настройки могут гарантировать, что последующие вызовы подсистемы вызовут исключение , зависание без ответа или возврат null
и т. Д. Таким образом, можно разработать и протестировать поведение клиента для реалистичных условий сбоя в серверной части. подсистемы, а также их ожидаемые ответы. Без такой простой и гибкой имитирующей системы тестирование каждой из этих ситуаций может оказаться слишком трудоемким для их рассмотрения.
Запись строк журнала
save(person : Person)
Метод объекта фиктивной базы данных может не содержать большого количества кода реализации (если таковой имеется). Он может проверять наличие и, возможно, действительность объекта Person, переданного для сохранения (см. Обсуждение фальшивого и фиктивного выше), но помимо этого другой реализации может и не быть.
Это упущенная возможность. Макетный метод может добавить запись в строку общедоступного журнала. Запись должна быть не более чем «Человек сохранен», [9] : 146–7 или может включать некоторые детали из экземпляра объекта человека, такие как имя или идентификатор. Если тестовый код также проверяет окончательное содержимое строки журнала после различных серий операций с фиктивной базой данных, то можно проверить, что в каждом случае было выполнено точно ожидаемое количество сохранений базы данных. Это может найти в противном случае невидимые ошибки, снижающие производительность, например, когда разработчик, нервничающий из-за потери данных, закодировал повторяющиеся вызовы save()
там, где было бы достаточно всего одного.
Использование в разработке через тестирование
Программисты, работающие с методом разработки через тестирование (TDD), используют фиктивные объекты при написании программного обеспечения. Мок-объекты соответствуют требованиям интерфейса и заменяют более сложные реальные; таким образом, они позволяют программистам писать и тестировать функциональные возможности в одной области, не вызывая сложных базовых или взаимодействующих классов . [9] : 144–5 Использование фиктивных объектов позволяет разработчикам сосредоточить свои тесты на поведении тестируемой системы, не беспокоясь о ее зависимостях. Например, тестирование сложного алгоритма, основанного на нескольких объектах, находящихся в определенных состояниях, может быть четко выражено с помощью фиктивных объектов вместо реальных.
Помимо проблем сложности и преимуществ, получаемых от такого разделения задач , существуют практические проблемы скорости. Разработка реалистичного программного обеспечения с использованием TDD может легко включать в себя несколько сотен модульных тестов. Если многие из них вызывают связь с базами данных, веб - сервисов и других вне процесса или сетевых систем, то набор модульных тестов быстро станет слишком медленно , чтобы регулярно работать. Это, в свою очередь, приводит к вредным привычкам и нежеланию разработчика поддерживать основные принципы TDD.
Когда фиктивные объекты заменяются реальными, сквозная функциональность потребует дальнейшего тестирования. Это будут интеграционные тесты, а не модульные тесты.
Ограничения
Использование фиктивных объектов может тесно связать модульные тесты с реализацией тестируемого кода. Например, многие фреймворки имитирующих объектов позволяют разработчику проверять порядок и количество вызовов методов имитационного объекта реальным тестируемым объектом; последующий рефакторинг тестируемого кода может привести к сбою теста, даже если все методы имитируемых объектов по-прежнему подчиняются контракту предыдущей реализации. Это показывает, что модульные тесты должны тестировать внешнее поведение метода, а не его внутреннюю реализацию. Чрезмерное использование имитирующих объектов в составе набора модульных тестов может привести к резкому увеличению объема обслуживания, которое необходимо выполнять над самими тестами во время эволюции системы по мере рефакторинга. Неправильное обслуживание таких тестов во время эволюции может позволить пропустить ошибки, которые в противном случае были бы обнаружены модульными тестами, использующими экземпляры реальных классов. И наоборот, простая имитация одного метода может потребовать гораздо меньше настроек, чем настройка всего реального класса, и, следовательно, снизить потребности в обслуживании.
Имитируемые объекты должны точно моделировать поведение объекта, который они высмеивают, чего может быть трудно достичь, если объект, который подвергается издевательству, исходит от другого разработчика или проекта или если он еще даже не был написан. Если поведение не смоделировано правильно, то модульные тесты могут зарегистрировать прохождение, даже если сбой произойдет во время выполнения при тех же условиях, что и модульный тест, что делает модульный тест неточным. [10]
Смотрите также
Рекомендации
- ^ «Давайте говорить на одном языке (фейки, заглушки и макеты)» .
- ^ «отстает от времени: макеты и заглушки не шпионы» . 21 октября 2007 г.
- ^ «Моки, подделки, заглушки и манекены на XUnitPatterns.com» .
- ^ "В чем разница между макетом и заглушкой?" .
- ^ «В чем разница между притворством, издевательством и заглушкой?» .
- ^ Перья, Майкл (2005). «Чувство и разделение». Эффективная работа с устаревшим кодом . Нью-Джерси: Прентис Холл. п. 23 и след. ISBN 0-13-117705-2.
- ^ Ошеров, Рой (2009). «Тестирование взаимодействия с фиктивными объектами и проч.». Искусство модульного тестирования . Укомплектование персоналом. ISBN 978-1-933988-27-6.
- ^ В этих примерах используется номенклатура, аналогичная той, которая используется в Unified Modeling Language.
- ^ а б Бек, Кент (2003). Разработка через тестирование на примере . Бостон: Эддисон Уэсли. ISBN 0-321-14653-0.
- ^ InJava.com к издевательству | O'Reilly Media
Внешние ссылки
- Тим Маккиннон (8 сентября 2009 г.). «Краткая история фиктивных объектов» . Mockobjects.com/.
- Test Doubles : раздел книги о шаблонах модульного тестирования.
- Все о фиктивных объектах! Портал о фиктивных объектах
- «Использование макетов объектов для сложных модульных тестов» . IBM developerWorks. 16 октября 2006 Архивировано из оригинала 4 мая 2007 года.
- Модульное тестирование с использованием фиктивных объектов IBM developerWorks
- Mocks - это не заглушки ( Мартин Фаулер ) Статья о разработке тестов с использованием Mock-объектов. Определяет и сравнивает "классическую" и "насмешливую" школы тестирования. Рассказывает о влиянии на дизайн и обслуживание.