Мокито
Мокито - модуль созданный по образу популярного java-фреймворка для тестирования Mockito. Расширяет возможности тестирования, позволяет легко менять логику работы системы подменяя результаты работы методов, отключая какие-либо алгоритмы и проверки.
Возможности
С помощью Мокито мы можем с легкостью управлять поведением системы прямо из теста, для этого есть возможность:
- Настраивать какие методы "меняют" свое поведение, а какие обрабатывают "как положено".
- Для разных тестов или кейсов внутри теста можно перенастраивать поведение методов.
- Задавать условия на параметры метода.
- Мокировать как экспортные так и приватные методы, процедуры и функции.
- Настраивать разные "реакции" на вызов метода:
- Вернуть указанный результат
- Вызвать исключение
- Не выполнять метода
- Просто наблюдать за методом (собирать статистику по вызовам)
Вы можете мокировать почти любой метод конфигурации, исключение - методы глобального контекста.
- Методы общих модулей
- Методы менеджеров
- Методы конкретных объектов, будь то документы или справочники
Примеры:
- Для всех объектов определенного типа - обучаете через менеджер
Мокито.Обучение(Документы.ПриходТовара) // Для всех документов ПриходТовара
.Когда("ОбработкаПроведения") - Если нужно мокировать метод экземпляра объекта, то указываем его при обучении
Мокито.Обучение(ДокументОбъект) // Для конкретного экземпляра объекта,
.Когда("ОбработкаПроведения") // другой документ объект, даже полученный из той же ссылки отработает без мокирования - либо ссылку на этот объект
Мокито.Обучение(ДокументСсылка) // Любой документ объект с той же ссылкой
.Когда("ОбработкаПроведения") - Можно мокировать методы обработок и отчетов
Мокито.Обучение(Отчеты.ОСВ) // Для всех отчетов
.Когда("СформироватьОтчет")
Отчет = Отчеты.ОСВ.СоздатьОтчет();
Мокито.Обучение(Отчет) // для конкретного экземпляра отчета
.Когда("СформироватьОтчет")
Мокито не может:
- Выполнять произвольную логику при вызове - выполнить алгоритм или вызвать какой-либо другой метод.
- Не может изменять параметры.
- При сборе статистики не хранит результат.
Принцип работы
Мокито базируется на двух вещах:
- Расширения и заимствование методов, благодаря им появилась возможность менять поведение системы.
- Глобальный контекст, доступный как из теста, так и из заимствованных методов конфигурации.
Настройка мокируемых методов
Для того чтобы вы смогли мокировать метода, вам в первую очередь необходимо добавить его в свое расширение.
И добавить реализацию по шаблону для функции:
&Вместо("<ИмяМокируемогоМетода>")
Функция Мок_<ИмяМокируемогоМетода>(<ПараметрыМетода>)
ПараметрыМетода = Мокито.МассивПараметров(<ПараметрыМетода>);
ПрерватьВыполнение = Ложь;
Результат = МокитоПерехват.АнализВызова(<МокируемыйОбъект>, "<ИмяМокируемогоМетода>", ПараметрыМетода, ПрерватьВыполнение);
Если Не ПрерватьВыполнение Тогда
Возврат ПродолжитьВызов(<ПараметрыМетода>);
Иначе
Возврат Результат;
КонецЕсли;
КонецФункции
Либо для процедуры:
&Вместо("<ИмяМокируемогоМетода>")
Процедура Мок_<ИмяМокируемогоМетода>(<ПараметрыМетода>)
ПараметрыМетода = Мокито.МассивПараметров(<ПараметрыМетода>);
ПрерватьВыполнение = Ложь;
МокитоПерехват.АнализВызова(<МокируемыйОбъект>, "<ИмяМокируемогоМ етода>", ПараметрыМетода, ПрерватьВыполнение);
Если Не ПрерватьВыполнение Тогда
ПродолжитьВызов(<ПараметрыМетода>);
КонецЕсли;
КонецПроцедуры
Если метод не содержит параметров можно использовать пустой массив:
ПараметрыМетода = Новый Массив;
Если вы используете 1С:Enterprise Development Tools (EDT), то можете воспользоваться контекстной командой 1С:Модульные тесты (YAxUnit)
-> Создать/обновить мок для...
Примеры добавления методов в расширение.
Метод общего модуля
Добавляем обработку метода ПолучитьПрофиль
общего модуля РаботаСПочтой
&Вместо("ПолучитьПрофиль")
Функция Мок_ПолучитьПрофиль(ИмяОтправителя, ИспользоватьIMAP) Экспорт
// Собираем параметры в массив
ПараметрыМетода = Мокито.МассивПараметров(ИмяОтправи теля, ИспользоватьIMAP);
// Отправляем данные на анализ
ПрерватьВыполнение = Ложь;
Результат = МокитоПерехват.АнализВызова(РаботаСПочтой, "ПолучитьПрофиль", ПараметрыМетода, Прерват ьВыполнение);
// Обрабатываем результат анализа
Если НЕ ПрерватьВыполнение Тогда
Возврат ПродолжитьВызов(ИмяОтправителя, ИспользоватьIMAP);
Иначе
Возврат Результат;
КонецЕсли;
КонецФункции
Метод модуля менеджера
Подходит для любого модуля менеджера, будь то, документ, регистр или отчет.
Добавляем обработку метода НовыйИдентификаторПодписчикаУведомлений
модуля менеджера справочника Справочники.МобильныеУстройства
&Вместо("НовыйИдентификаторПодписчикаУведомлений")
Процедура Мок_НовыйИдентификаторПодписчикаУведомлений(Подписчик, Идентификатор) Экспорт
// Собираем параметры в массив
ПараметрыМетода = Мокито.МассивПараметров(Подписчик, Идентификатор);
// Отправляем данные на анализ
ПрерватьВыполнение = Ложь;
МокитоПерехват.АнализВызова(Справочники.МобильныеУстройства, "НовыйИдентификаторПодписчикаУведомлений", ПараметрыМетода, ПрерватьВыполнение);
// Обрабатываем результат анализа
Если НЕ ПрерватьВыполнение Тогда
ПродолжитьВызов(Подписчик, Идентификатор);
КонецЕсли;
КонецПроцедуры
Метод модуля объекта
Добавляем обработку приватного метода ОбработкаПроведения
модуля объекта справочника Документ.ПриходТовара
&Вместо("ОбработкаПроведения")
Процедура Мок_ОбработкаПроведения(Отказ, Режим)
// Собираем параметры в массив
ПараметрыМетода = Мокито.МассивПараметров(Отказ, Режим);
// Отправляем данные на анализ
ПрерватьВыполнение = Ложь;
МокитоПерехват.АнализВызова(ЭтотОбъект, "ОбработкаПроведения", ПараметрыМетода, ПрерватьВыполнение);
// Обрабатываем результат анализа
Если НЕ ПрерватьВыполнение Тогда
ПродолжитьВызов(Отказ, Режим);
КонецЕсли;
КонецПроцедуры
После этого, вы может управлять поведение метода из ваших тестов.
Тестирование с использованием Мокито можно разделить на 3 стадии:
- Сначала вы проводите обучение - настраиваете, какие методы мокируем и как они должны себя вести.
- Потом выполняете тестовый прогон целевого метода.
- После вам может понадобиться проверка вызовов, были ли вызваны нужные метода, с какими параметрами.
// Подготовка
Ответ = Новый HTTPСервисОтвет(1);
Ответ.УстановитьТелоИзСтроки(СериализацияJSON.ЗначениеВСтроку(Новый Структура("id, status",
"9999",
"delivered")));
// Обучение мокито
Мокито.Обучение(ОтправкаСМС_Провайдер1)
.Когда("УстановитьСоединение").Вернуть(Истина)
.Когда("ПослатьСообщение").Вернуть(Ответ)
.Прогон();
// Тестовый прогон
РоботОтправки.ОтправкаСМС();
// Проверка статистики
Мокито.Проверить(ОтправкаСМС_Провайдер1)
.КоличествоВызовов("ПослатьСообщение")
.Равно(1);
Подробнее расскажу по каждой стадии
Обучение
Обучение - это процесс настройки мокито. Вы указываете какие методы и при каких условиях (параметрах) должны изменить свое поведение.
С помощью API вы можете:
Наблюдать()
- просто наблюдать за методом, собирать статистику.Когда()
- указать какой метод и с каким параметрами необходимо обрабатывать.Вернуть()
- настроить, чтобы метод возвращал нужный результат.ВыброситьИсключение()
- настроить, чтобы метод выбрасывал исключение.Пропустить()
- настроить, чтобы метод был пропущен, не выполнился.ВыполнитьМетод()
- настроить, чтобы метод выполнился как есть.
Мокито.Обучение(ОтправкаСМС_Провайдер1)
.Когда("УстановитьСоединение").Пропустить()
.Когда("ПослатьСообщение").Вернуть(Ответ)
.Наблюдать("ОбработатьОтвет")
Подробнее о методах ниже, а сейчас для лучшего понимания расскажу как работает обучение.
Используя методы API вы формируете настройки Мокито
, которые при вызове каждого метода обучения изменяются и сохраняются в глобальном контексте движка. Каждый метод просто сохраняет нужным образом параметры в глобальные структуру.
Каждый вызов метода Мокито.Обучение
, по умолчанию, очищает предыдущие настройки по указанному объекту. Это нужно учитывать когда вы доучиваете Мокито в тесте.
Если вам не нужно сбрасывать старые настройки по объекту передайте соответствующий параметр
Мокито.Обучение(ОтправкаСМС_Провайдер1)
.Когда("УстановитьСоединение").Пропустить()
.Когда("ПослатьСообщение").Вернуть(Ответ)
.Наблюдать("ОбработатьОтвет")
.Прогон();
// Какая то логика
Мокито.Обучение(ОтправкаСМС_Провайдер1, Ложь) // Дообучение
.Когда("ПослатьСообщение").Вернуть(Ответ2);
В процессе обучения мы создаем правила, описывающие как будет вести себя метод при различных вариантах вызова. Правила состоят из двух частей
- условие срабатывания (об/ект, метод, параметры), задаются в методе
Когда
илиНаблюдать
- действие выполняемое при соблюдении условий -
Вернуть
,ВыброситьИсключение
,Пропустить
,ВыполнитьМетод