Введение
Объект программного обеспечения, имитирующий реальный объект.
Мок-объект – это объект, имитирующий рабочий объект ограниченным образом. Программист может использовать мок-объект в качестве тестового двойника при тестировании программного обеспечения. Мок-объект также может применяться в обобщённом программировании.
Аналогия
Модель объекта может быть полезна тестировщику программного обеспечения, как конструктор автомобиля использует манекен при краш-тестах для имитации человека при столкновении транспортного средства.
Технические детали
Мок-объекты имеют тот же интерфейс, что и реальные объекты, которые они имитируют, позволяя объекту-клиенту не знать, использует он реальный объект или мок-объект. Многие доступные фреймворки для создания мок-объектов позволяют программисту указать, какие методы будут вызваны у мок-объекта, в каком порядке, какие параметры будут переданы этим методам и какие значения будут возвращены. Таким образом, поведение сложного объекта, например, сетевого сокета, можно имитировать с помощью мок-объекта, что позволяет программисту проверить, правильно ли тестируемый объект реагирует на широкий спектр состояний, в которых могут находиться такие мок-объекты.
Моки, подделки и кусочки
Определения моков, фейков и стабов не являются последовательными в литературе. Тем не менее, все они представляют собой производственный объект в тестовой среде, предоставляя тот же интерфейс. Независимо от названия, простейшая форма возвращает заранее заданные ответы (как в случае со стабом метода), а наиболее сложная форма имитирует полную логику производственного объекта. Такой тестовый объект может содержать утверждения для проверки контекста каждого вызова. Например, мок-объект может проверять порядок вызова его методов или согласованность данных между вызовами методов. В книге "Искусство модульного тестирования" моки описываются как фейковые объекты, которые помогают определить, прошел или не прошел тест, путем проверки факта взаимодействия с объектом. Все остальное определяется как стаб. В этой книге фейки – это все, что не является реальным, и, в зависимости от их использования, может быть как стабами, так и моками.
Определение ожиданий
Рассмотрим пример, когда подсистема авторизации была замокирована. Замокированный объект реализует метод `isUserAllowed(task : Task) : boolean`, соответствующий методу в реальном классе авторизации. Появляется ряд преимуществ, если он также предоставляет свойство `isAllowed : boolean`, отсутствующее в реальном классе. Это позволяет тестовому коду легко задавать ожидание, что пользователю будет или не будет предоставлено разрешение при следующем вызове, и, следовательно, легко тестировать поведение остальной системы в обоих случаях. Аналогично, можно использовать только замокированные настройки, чтобы последующие вызовы подсистемы приводили к выбросу исключения, зависанию без ответа или возврату null и т.д. Таким образом, можно разрабатывать и тестировать поведение клиента для реалистичных сценариев отказов в подсистемах бэкенда, а также для их ожидаемых ответов. Без такой простой и гибкой системы замокирования, тестирование каждой из этих ситуаций может оказаться слишком трудоемким, чтобы уделить ей должное внимание.
Запись строки журналов
Метод `save(person : Person)` объекта-заглушки базы данных может не содержать большого количества (или вообще никакого) кода реализации. Он может проверять существование и, возможно, корректность объекта `Person`, переданного для сохранения (см. обсуждение различий между заглушкой и макетом выше), но на этом его реализация может заканчиваться. Это упущенная возможность. Метод-заглушка мог бы добавлять запись в публичную строку журнала. Запись может быть простой, например, "Объект Person сохранен", или включать некоторые детали из экземпляра объекта `Person`, такие как имя или идентификатор. Если тестовый код также проверяет окончательное содержимое строки журнала после различных последовательностей операций с использованием заглушки базы данных, то можно убедиться, что в каждом случае было выполнено ровно ожидаемое количество сохранений в базу данных. Это позволяет выявлять скрытые ошибки, снижающие производительность, например, когда разработчик, опасаясь потери данных, пишет повторяющиеся вызовы `save`, хотя одного было бы достаточно.
Использование в тестовой разработке
Программисты, работающие с методологией разработки через тестирование (TDD), используют имитирующие объекты при написании программного обеспечения. Имитирующие объекты соответствуют требованиям интерфейса и заменяют более сложные реальные объекты, позволяя программистам разрабатывать и модульно тестировать функциональность в определенной области, не обращаясь к сложным базовым или взаимодействующим классам.