Принципы работы Мокито
Основные принципы работы Мокито
Мокито работает на основе двух ключевых компонентов:
- Расширение методов конфигурации: Мокито заменяет реальные методы конфигурации на специальные обработчики, которые позволяют управлять их поведением.
- Глобальный контекст: Все настройки мокирования и статистика вызовов хранятся в глобальном контексте, что позволяет синхронизировать данные между тестами и мокируемыми методами.
Как Мокито заменяет методы?
Мокито использует механизм расширения конфигурации, чтобы перехватить вызовы методов. Для этого:
-
Методы добавляются в расширение:
Методы конфигурации заимствуются в расширении с директивой&Вместо
. Это позволяет переопределить их поведение в рамках тестов. -
Заимствованные методы оформляются по специальному шаблону:
Методы оформляются по шаблону, который позволяет управлять вызовами метода. Шаблон включает логику для анализа параметров и применения настроек мокирования. -
Обработчики перехватывают вызовы:
Когда метод вызывается, вместо реальной логики выполняется обработчик, который анализирует вызов и применяет настройки мокирования. Это позволяет изменять поведение метода в зависимости от условий. -
Вызов основного метода конфигурации:
Если вызов не подходит под условия, указанные в тесте, выполняется вызов основного метода конфигурации с помощьюПродолжитьВызов
. Это обеспечивает гибкость, позволяя тестам работать как с мокированными, так и с реальными методами.
Глобальный контекст
Мокито использует глобальный контекст для хранения настроек мокирования и статистики вызовов. Это позволяет:
-
Выполнять из теста настройку мокирования:
Настройки мокирования, такие как возвращаемые значения, исключения или условия вызова, задаются в тесте и сохраняются в глобальном контексте. Это делает процесс настройки простым и удобным. -
Методы-перехватчики могут читать настройки из глобального контекста:
Когда метод вызывается, перехватчик обращае тся к глобальному контексту, чтобы получить актуальные настройки мокирования. Это обеспечивает согласованность между тестами и мокированными методами. -
Собирать статистику по вызовам методов:
Вся информация о вызовах методов (количество вызовов, параметры) сохраняется в глобальном контексте. Эта статистика доступна в тесте для анализа, что позволяет проверять корректность работы тестируемого кода.
Таким образом, глобальный контекст служит централизованным хранилищем для управления мокированием и анализа вызовов, обеспечивая гибкость и удобство при написании тестов.
Этапы работы Мокито
Этап обучения
Обучение — это настройка Мокито, в ходе которой указываются условия мокирования методов и действия, выполняемые при мокировании.
Используя программный интерфейс Мокито, в тесте указываются условия перехвата методов:
-
Объект-владелец метода:
Указывается с помощьюМокито.Обучение(Объект)
. Это объект, метод которого будет мокироваться. -
Имя метода:
Указывается с помощьюКогда(ИмяМетода)
илиНаблюдать(ИмяМетода)
. Определяет, какой именно метод будет перехвачен. -
Параметры вызова (при необходимости):
Указываются с помощьюКогда(ИмяМетода, КоллекцияПараметров)
илиНаблюдать(ИмяМетода, КоллекцияПараметров)
. Позволяет задать условия для параметров метода.
Пример
// Начинаем настройку мокирования для объекта "РаботаСHTTP"
Мокито.Обучение(РаботаСHTTP)
// Указываем, что мокируем метод "ОтправитьОбъектНаСервер"
// и задаем параметры вызова: "ИсточникДанных" и "Данные"
.Когда("ОтправитьОбъектНаСервер", Мокито.МассивПараметров(ИсточникДанных, Данные))
// Настраиваем метод на возврат значения "2" при вызове с указанными параметрами
.Вернуть(2);
В этом примере:
- Условие: Метод
ОтправитьОбъектНаСервер
общего модуляРаботаСHTTP
вызывается с параметрамиИсточникДанных
иДанные
. - Реакция: Метод возвращает значение
2
.
Особенности настройки условий на параметры вызова
- Если параметры не указаны, под условия подходят все вызовы метода.
- Если часть параметров не указана (например, первые два из трех), то под условия попадают вызовы, для которых совпадают указанные параметры. Остальные параметры не влияют на успешность проверки условия.
- Вместо конкретных значений параметров можно использовать предикаты и шаблоны:
Мокито.ЛюбойПараметр()
: Подходит любой параметр.Мокито.ЧисловойПараметр()
: Подходит любой числовой параметр.Мокито.СтроковыйПараметр()
: Подходит любой строковый параметр.Мокито.ТипизированныйПараметр(Тип)
: Подходит параметр указанного типа.
Если значение параметра не важно, можно использовать маску Мокито.ЛюбойПараметр()
. Однако, если это последний параметр, его можно не указывать — эффект будет тем же. Это упрощает код и делает его более читаемым.
// 1. Полная запись с использованием маски "ЛюбойПараметр" для второго параметра
// Указываем, что первый параметр должен быть "ПравильныйАдрес", а второй параметр может быть любым.
Мокито.Обучение(РаботаСHTTP)
.Когда("ОтправитьОбъектНаСервер", МассивПараметров(ПравильныйАдрес, Мокито.ЛюбойПараметр()));
// 2. Упрощенная запись (если последний параметр не важен)
// Второй параметр можно не указывать, так как он автоматически считается "любым".
Мокито.Обучение(РаботаСHTTP)
.Когда("ОтправитьОбъектНаСервер", МассивПараметров(ПравильныйАдрес));
Особенности обучения для объектов конфигурации
Для каждого объекта конфигурации существуют разные типы данных
- Менеджер объетка
- Объект конфигурации
- Ссылка на объект
Менеджер и объект имеют свои наборы методов, а ссылка имеет только платформенные методы. С одной стороны все просто, для мокирования методов менеджера стоит обучать менеджер, а для методов объекта - объет. Но как быть если требуется мокировать метод для любого объекта или у нас нет самого объекта, а есть ссылка на него или объект создается в тестируемом коде.
Для решения этих проблем в Мокито была добавлена кастомная логика:
- Через менеджер можно мокировать методы любого объекта
- Через ссылку - методы объекта с указанной ссылкой
Методы менеджера | Методы объект | |
---|---|---|
Обучение через менеджер | + | Для всех объектов |
Обучение через объект | - | Для конкретного объекта |
Обучение через ссылку | - | Для объектов с этой ссылкой |