Перейти к основному содержимому

Мокито

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

Возможности

С помощью Мокито мы можем с легкостью управлять поведением системы прямо из теста, для этого есть возможность:

  • Настраивать какие методы "меняют" свое поведение, а какие обрабатывают "как положено".
  • Для разных тестов или кейсов внутри теста можно перенастраивать поведение методов.
  • Задавать условия на параметры метода.
  • Мокировать как экспортные так и приватные методы, процедуры и функции.
  • Настраивать разные "реакции" на вызов метода:
    • Вернуть указанный результат
    • Вызвать исключение
    • Не выполнять метода
    • Просто наблюдать за методом (собирать статистику по вызовам)

Вы можете мокировать почти любой метод конфигурации, исключение - методы глобального контекста.

  1. Методы общих модулей
  2. Методы менеджеров
  3. Методы конкретных объектов, будь то документы или справочники

Примеры:

  • Для всех объектов определенного типа - обучаете через менеджер
    Мокито.Обучение(Документы.ПриходТовара) // Для всех документов ПриходТовара
    .Когда("ОбработкаПроведения")
  • Если нужно мокировать метод экземпляра объекта, то указываем его при обучении
    Мокито.Обучение(ДокументОбъект) // Для конкретного экземпляра объекта, 
    .Когда("ОбработкаПроведения") // другой документ объект, даже полученный из той же ссылки отработает без мокирования
  • либо ссылку на этот объект
    Мокито.Обучение(ДокументСсылка) // Любой документ объект с той же ссылкой
    .Когда("ОбработкаПроведения")
  • Можно мокировать методы обработок и отчетов
    Мокито.Обучение(Отчеты.ОСВ) // Для всех отчетов
    .Когда("СформироватьОтчет")

    Отчет = Отчеты.ОСВ.СоздатьОтчет();
    Мокито.Обучение(Отчет) // для конкретного экземпляра отчета
    .Когда("СформироватьОтчет")

Мокито не может:

  • Выполнять произвольную логику при вызове - выполнить алгоритм или вызвать какой-либо другой метод.
  • Не может изменять параметры.
  • При сборе статистики не хранит результат.

Принцип работы

Мокито базируется на двух вещах:

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

Настройка мокируемых методов

Для того чтобы вы смогли мокировать метода, вам в первую очередь необходимо добавить его в свое расширение.

И добавить реализацию по шаблону для функции:

&Вместо("<ИмяМокируемогоМетода>")
Функция Мок_<ИмяМокируемогоМетода>(<ПараметрыМетода>)
ПараметрыМетода = Мокито.МассивПараметров(<ПараметрыМетода>);
ПрерватьВыполнение = Ложь;

Результат = МокитоПерехват.АнализВызова(<МокируемыйОбъект>, "<ИмяМокируемогоМетода>", ПараметрыМетода, ПрерватьВыполнение);

Если Не ПрерватьВыполнение Тогда
Возврат ПродолжитьВызов(<ПараметрыМетода>);
Иначе
Возврат Результат;
КонецЕсли;
КонецФункции

Либо для процедуры:

&Вместо("<ИмяМокируемогоМетода>")
Процедура Мок_<ИмяМокируемогоМетода>(<ПараметрыМетода>)
ПараметрыМетода = Мокито.МассивПараметров(<ПараметрыМетода>);
ПрерватьВыполнение = Ложь;

МокитоПерехват.АнализВызова(<МокируемыйОбъект>, "<ИмяМокируемогоМетода>", ПараметрыМетода, ПрерватьВыполнение);

Если Не ПрерватьВыполнение Тогда
ПродолжитьВызов(<ПараметрыМетода>);
КонецЕсли;
КонецПроцедуры
подсказка

Если метод не содержит параметров можно использовать пустой массив:

ПараметрыМетода = Новый Массив;

Если вы используете 1С:Enterprise Development Tools (EDT), то можете воспользоваться контекстной командой 1С:Модульные тесты (YAxUnit) -> Создать/обновить мок для...

edt-create-mock

Примеры добавления методов в расширение.

Метод общего модуля

Добавляем обработку метода ПолучитьПрофиль общего модуля РаботаСПочтой

tests\ОбщиеМодули\РаботаСПочтой\Модуль.bsl
&Вместо("ПолучитьПрофиль")
Функция Мок_ПолучитьПрофиль(ИмяОтправителя, ИспользоватьIMAP) Экспорт
// Собираем параметры в массив
ПараметрыМетода = Мокито.МассивПараметров(ИмяОтправителя, ИспользоватьIMAP);

// Отправляем данные на анализ
ПрерватьВыполнение = Ложь;
Результат = МокитоПерехват.АнализВызова(РаботаСПочтой, "ПолучитьПрофиль", ПараметрыМетода, ПрерватьВыполнение);

// Обрабатываем результат анализа
Если НЕ ПрерватьВыполнение Тогда
Возврат ПродолжитьВызов(ИмяОтправителя, ИспользоватьIMAP);
Иначе
Возврат Результат;
КонецЕсли;
КонецФункции

Метод модуля менеджера

Подходит для любого модуля менеджера, будь то, документ, регистр или отчет.

Добавляем обработку метода НовыйИдентификаторПодписчикаУведомлений модуля менеджера справочника Справочники.МобильныеУстройства

tests\Справочники\МобильныеУстройства\МодульМенеджера.bsl
&Вместо("НовыйИдентификаторПодписчикаУведомлений")
Процедура Мок_НовыйИдентификаторПодписчикаУведомлений(Подписчик, Идентификатор) Экспорт

// Собираем параметры в массив
ПараметрыМетода = Мокито.МассивПараметров(Подписчик, Идентификатор);

// Отправляем данные на анализ
ПрерватьВыполнение = Ложь;
МокитоПерехват.АнализВызова(Справочники.МобильныеУстройства, "НовыйИдентификаторПодписчикаУведомлений", ПараметрыМетода, ПрерватьВыполнение);

// Обрабатываем результат анализа
Если НЕ ПрерватьВыполнение Тогда
ПродолжитьВызов(Подписчик, Идентификатор);
КонецЕсли;

КонецПроцедуры

Метод модуля объекта

Добавляем обработку приватного метода ОбработкаПроведения модуля объекта справочника Документ.ПриходТовара

tests\Документы\ПриходТовара\МодульОбъекта.bsl
&Вместо("ОбработкаПроведения")
Процедура Мок_ОбработкаПроведения(Отказ, Режим)

// Собираем параметры в массив
ПараметрыМетода = Мокито.МассивПараметров(Отказ, Режим);

// Отправляем данные на анализ
ПрерватьВыполнение = Ложь;
МокитоПерехват.АнализВызова(ЭтотОбъект, "ОбработкаПроведения", ПараметрыМетода, ПрерватьВыполнение);

// Обрабатываем результат анализа
Если НЕ ПрерватьВыполнение Тогда
ПродолжитьВызов(Отказ, Режим);
КонецЕсли;

КонецПроцедуры

После этого, вы может управлять поведение метода из ваших тестов.

Тестирование с использованием Мокито можно разделить на 3 стадии:

  1. Сначала вы проводите обучение - настраиваете, какие методы мокируем и как они должны себя вести.
  2. Потом выполняете тестовый прогон целевого метода.
  3. После вам может понадобиться проверка вызовов, были ли вызваны нужные метода, с какими параметрами.
  // Подготовка
Ответ = Новый HTTPСервисОтвет(1);
Ответ.УстановитьТелоИзСтроки(СериализацияJSON.ЗначениеВСтроку(Новый Структура("id, status",
"9999",
"delivered")));

// Обучение мокито
Мокито.Обучение(ОтправкаСМС_Провайдер1)
.Когда("УстановитьСоединение").Вернуть(Истина)
.Когда("ПослатьСообщение").Вернуть(Ответ)
.Прогон();

// Тестовый прогон
РоботОтправки.ОтправкаСМС();

// Проверка статистики
Мокито.Проверить(ОтправкаСМС_Провайдер1)
.КоличествоВызовов("ПослатьСообщение")
.Равно(1);

Подробнее расскажу по каждой стадии

Обучение

Обучение - это процесс настройки мокито. Вы указываете какие методы и при каких условиях (параметрах) должны изменить свое поведение.

С помощью API вы можете:

  • Наблюдать() - просто наблюдать за методом, собирать статистику.
  • Когда() - указать какой метод и с каким параметрами необходимо обрабатывать.
  • Вернуть() - настроить, чтобы метод возвращал нужный результат.
  • ВыброситьИсключение() - настроить, чтобы метод выбрасывал исключение.
  • Пропустить() - настроить, чтобы метод был пропущен, не выполнился.
  • ВыполнитьМетод() - настроить, чтобы метод выполнился как есть.
Мокито.Обучение(ОтправкаСМС_Провайдер1)
.Когда("УстановитьСоединение").Пропустить()
.Когда("ПослатьСообщение").Вернуть(Ответ)
.Наблюдать("ОбработатьОтвет")

Подробнее о методах ниже, а сейчас для лучшего понимания расскажу как работает обучение.
Используя методы API вы формируете настройки Мокито, которые при вызове каждого метода обучения изменяются и сохраняются в глобальном контексте движка. Каждый метод просто сохраняет нужным образом параметры в глобальные структуру.

Сброс старых настроек

Каждый вызов метода Мокито.Обучение, по умолчанию, очищает предыдущие настройки по указанному объекту. Это нужно учитывать когда вы доучиваете Мокито в тесте.
Если вам не нужно сбрасывать старые настройки по объекту передайте соответствующий параметр

Мокито.Обучение(ОтправкаСМС_Провайдер1)
.Когда("УстановитьСоединение").Пропустить()
.Когда("ПослатьСообщение").Вернуть(Ответ)
.Наблюдать("ОбработатьОтвет")
.Прогон();
// Какая то логика

Мокито.Обучение(ОтправкаСМС_Провайдер1, Ложь) // Дообучение
.Когда("ПослатьСообщение").Вернуть(Ответ2);

В процессе обучения мы создаем правила, описывающие как будет вести себя метод при различных вариантах вызова. Правила состоят из двух частей

  • условие срабатывания (об/ект, метод, параметры), задаются в методе Когда или Наблюдать
  • действие выполняемое при соблюдении условий - Вернуть, ВыброситьИсключение, Пропустить, ВыполнитьМетод

Условия

Условие состоит из трех частей

  • Объект, которому относится метод
  • Имя метода
  • Параметры метода
Объект

Объект является обязательным и задается в методе Мокито.Обучение().

В качестве объекта могут выступать:

  • Менеджер объекта метаданных, в таком случае под условие попадают все обращения к этому типу метаданных, будь вызовы методов модуля менеджера или объекта.
  • Ссылка, под условие попадают все обращения к объектам имеющим ту же ссылку.
  • Объект - конкретный объект метаданных (документ, обработка, набор записей), только обращения к методам этого экземпляра объекта.
Имя метода

Имя метода, является обязательным. Указывается в методах Когда или Наблюдать. Можно обрабатывать и экспортные и приватные метода, главное чтобы для него была выполнена настройка

Параметры

Указывается в методах Когда или Наблюдать, передачей массива ожидаемых параметров.

Необязательная часть условия, если не указывать, но будут обрабатывать все вызовы.
Также необязательно указывать все параметры метода, достаточно указать только первую часть.

В качестве параметров можно указывать:

  • Конкретные значения параметров
  • Маски
  • Предикаты, параметр должен соответствовать заданным условиям.
     Мокито.Обучение(РаботаСHTTP)
    .Когда(РаботаСHTTP.ОтправитьОбъектНаСервер(ИсточникДанных, ЮТест.Предикат().НеИмеетСвойства("Авторизация")))
    .Вернуть(ОтветНеобходимаАвторизация())
Варианты обучения (формирования условий)

Существует 2 основных подхода к формированию условий вызова:

  1. Явный вызов метода с параметрами
    Мокито.Обучение(РаботаСHTTP)
    .Когда(РаботаСHTTP.ОтправитьОбъектНаСервер(ИсточникДанных, Данные))
    .Вернуть(2)
  2. Указание имени метода и набора параметров
    Мокито.Обучение(РаботаСHTTP)
    .Когда("ОтправитьОбъектНаСервер", Мокито.МассивПараметров(ИсточникДанных, Данные))
    .Вернуть(2)

Первый вариант имеет ряд недостатков:

  1. Работает только для экспортных методов
  2. Необходимо передавать все обязательные параметры или использовать для них маску Мокито.ЛюбойПараметр()
  3. Если не указывать необязательные параметры, то их значения по умолчанию попадут в настройку. Покажу на примере.
    // Имеется метод 
    Функция Метод(Параметр1, Параметр2, Параметр3 = 3) Экспорт
    Возврат Параметр1 + Параметр2 + Параметр3;
    КонецФункции

    Мокито.Обучение(...)
    .Когда(Метод(1, 2))
    .Вернуть(0)
    .Прогон();

    Метод(1, 2); // Вернет 0
    Метод(1, 2, 3); // Вернут 0
    Метод(1, 2, 4); // Вернут 7, будет выполнен основной алгоритм

    // Второй вариант обучения
    Мокито.Обучение(...)
    .Когда("Метод", Мокито.МассивПараметров(1, 2))
    .Вернуть(0)
    .Прогон();

    Метод(1, 2); // Вернет 0
    Метод(1, 2, 3); // Вернут 0
    Метод(1, 2, 4); // Вернут 0

Действия (Реакции)

После того как определились с условием вызова указанным в методе Когда нужно указать реакцию (действие). Возможные реакции:

  • Вернуть - вернуть указанное значение
  • ВыброситьИсключение - вызвать исключение с переданным текстом
  • Пропустить - пропустить выполнение метод (актуально для процедур)
  • ВыполнитьМетод - выполнить основной метод конфигурации, обычно комбинируется к другими реакциями, чтобы задать исключение.
    Предположим, по умолчанию метод должен выбрасывать исключение, но для одного конкретного случая должен выполниться реальный метод конфигурации. Это проще всего сделать следующим образом:
    Мокито.Обучение(...)
    // По умолчанию метод падает
    .Когда("МегаФункция").ВыброситьИсключение("Упал")
    // При вызове с параметрами `1, 2, 3` выполняется метод конфигурации
    .Когда("МегаФункция", Мокито.МассивПараметров(1, 2, 3)).ВыполнитьМетод()
Пример мокирования методов документа
Документ = СоздатьДокумент();

Мокито.Обучение(Документ)
.Когда("ОбработкаПроверкиЗаполнения").Пропустить() // Отключим проверку заполнения документа
.Когда("КонтрольОстатков").Вернуть(Истина) // Проверка остатков будет успешной
.Когда("ЗафиксироватьОшибки").ВыброситьИсключение("Не должно быть ошибок") // При вызове "лишнего" кода сразу валим тест
.Когда("СформироватьПроводки")
.Пропустить() // Отключаем формирование таблицы движений
.Когда("СформироватьПроводки", Мокито.МассивПараметров("Взаиморасчеты"))
.ВыполнитьМетод() // Но включаем для регистра "Взаиморасчеты"
.Прогон(); // Завершаем настройку

Документ.Записать(РежимЗаписиДокумента.Проведение);
Цепочки действий

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


Мокито.Обучение(...)
.Когда("БытьИлиНеБыть")
.Вернуть("Быть") // Первый вызов метода вернет "Быть"
.Вернуть("Или") // Второй вызов
.Вернуть("НеБыть") // Третий
.ВыброситьИсключение("Конец") // Четвертый и все последующие

Примеры формирования различных вариантов условий

Имеется метод:
Функция ОтправитьОбъектНаСервер(ИсточникДанных, Объект, HTTPМетод = "POST",
ТипКонтента = "json", Преобразование = Неопределено,
ДопНастройки = Неопределено, Ответ = Неопределено, ОтветВСтруктуру = Ложь,
ТелоОтветаВХранилище = Ложь) Экспорт

Предположим необходимо:

  • Переопределить все вызовы метода - указываем имя метода без указания параметров
    Мокито.Обучение(РаботаСHTTP)
    .Когда("ОтправитьОбъектНаСервер").Вернуть(1)
  • Переопределить вызов, когда первый параметр имеет определенное значение
    Мокито.Обучение(РаботаСHTTP)
    .Когда("ОтправитьОбъектНаСервер", Мокито.МассивПараметров(ИсточникДанных))
    .Вернуть(2);

    // Через явный вызов метода
    Мокито.Обучение(РаботаСHTTP)
    .Когда(РаботаСHTTP.ОтправитьОбъектНаСервер(ИсточникДанных, Мокито.ЛюбойПараметр())
    .Вернуть(2) // Тут используется маска `Мокито.ЛюбойПараметр()`, тк второй параметр является обязательным
  • Переопределить вызов, когда второй параметр имеет определенное значение
    Мокито.Обучение(РаботаСHTTP)
    .Когда("ОтправитьОбъектНаСервер", Мокито.МассивПараметров(Мокито.ЛюбойПараметр(), Объект))
    .Вернуть(2);

    // Через явный вызов метода
    Мокито.Обучение(РаботаСHTTP)
    .Когда(РаботаСHTTP.ОтправитьОбъектНаСервер(Мокито.ЛюбойПараметр(), Объект)
    .Вернуть(2)
  • Условие на тип параметра
    // Первый параметр должен быть ссылкой на справочник, второй числом
    Мокито.Обучение(РаботаСHTTP)
    .Когда("ОтправитьОбъектНаСервер", Мокито.МассивПараметров(Мокито.ТипизированныйПараметр(Тип("СправочникСсылка.ИсточникиДанных")), Мокито.ЧисловойПараметр()))
    .Вернуть(3);

    // Через явный вызов метода
    Мокито.Обучение(РаботаСHTTP)
    .Когда(РаботаСHTTP.ОтправитьОбъектНаСервер(Мокито.ТипизированныйПараметр(Тип("СправочникСсылка.ИсточникиДанных")), Мокито.ЧисловойПараметр()))
    .Вернуть(3);
  • На основании порядка вызовов метода
    Мокито.Обучение(РаботаСHTTP)
    .Когда("ОтправитьОбъектНаСервер")
    .Вернуть(1)
    .Вернуть(2)
    .Вернуть(3)
    .ВыброситьИсключение("Конец");

Тестовый прогон

После обучения, настройки реакций на вызовы методов, можно запускать тест нужного метода.
Но перед этим необхдимо перевести Мокито в режим прогона тестов, для этого используется метод Мокито.Прогон().

Метод Прогон завершает настройку и изменяет режим работы, после этого все вызовы к настроенным методам (добавленным в расширение) будут перехватываться и анализироваться на совпадение условий вызова.

к сведению

Также метод Прогон очищает накопленную статистику прошлых прогонов. Если вам необходимо ее сохранить передайте Ложь в параметрах.

  • Для методов, которые были указаны в Когда() или Наблюдать(), будет собираться статистика вызовов.
  • Для методов, у которых есть подходящая "реакция" будет переопределено выполнение и запустится соответствующая реакция (вернуть значение, вызвать исключение и тд)
  • Для прочих методов (не настроенных) логика не изменится.
// Настройка
Мокито.Обучение(РаботаСHTTP)
.Когда("ОтправитьОбъектНаСервер", Мокито.МассивПараметров(Мокито.ЛюбойПараметр(), Мокито.ЛюбойПараметр()))
.Вернуть(РезультатПоУмолчанию)
.Когда("ОтправитьОбъектНаСервер", Мокито.МассивПараметров(Справочники.ИсточникиДанных.FTP, 2))
.Вернуть(2)
.Прогон(); // Перевод в режим прогона теста

Результат = РаботаСHTTP.ОтправитьОбъектНаСервер(ИсточникДанных, Данные); // Результат будет равен переменной РезультатПоУмолчанию
Результат = РаботаСHTTP.ОтправитьОбъектНаСервер(Справочники.ИсточникиДанных.FTP, 2); // Результат будет равен 2

Схема вызовов при вызове замокированного метода.

Проверка

После прогона теста можно проверить какие методы, с какими параметрами вызывались. Для этих целей необходимо воспользоваться методом Мокито.Проверить

ЛюбойПараметр = Мокито.ЛюбойПараметр();

Мокито.Проверить(РаботаСHTTP) // Устанавливаем проверяемый объект
// Проверка общего количества обращений к методу
.КоличествоВызовов("ОтправитьОбъектНаСервер")
.Заполнено()
.КоличествоВызовов(РаботаСHTTP.ОтправитьОбъектНаСервер(ЛюбойПараметр, ЛюбойПараметр))
.Равно(3)
// Проверка обращений с фильтром по типам параметров
.КоличествоВызовов(РаботаСHTTP.ОтправитьОбъектНаСервер(Мокито.ТипизированныйПараметр(ТипИсточникДанных), Мокито.ЧисловойПараметр())) // Условия поиска вызовов
.Больше(1) // Проверки
.Равно(2)
.КоличествоВызовов("ОтправитьОбъектНаСервер", Мокито.МассивПараметров(Мокито.ТипизированныйПараметр(ТипИсточникДанных), Мокито.ЧисловойПараметр()))
.Равно(2)
// Проверка обращений к методу с конкретными параметрами
.КоличествоВызовов("ОтправитьОбъектНаСервер", Мокито.МассивПараметров(1, 2))
.Равно(1)
.КоличествоВызовов(РаботаСHTTP.ОтправитьОбъектНаСервер(1, 2))
.Равно(1)

Принцип формирования проверки:

  • Указываем проверяемый объект Проверить(РаботаСHTTP).
  • Указываем условия поиска вызовов метода. Логика формирования условия такая же как при обучении. Например, КоличествоВызовов(РаботаСHTTP.ОтправитьОбъектНаСервер(ЛюбойПараметр, Мокито.ЧисловойПараметр())) Соберет все вызовы метода РаботаСHTTP.ОтправитьОбъектНаСервер, к которых вторым параметром идет число, а 3й и последующий параметры имеют значения по умолчанию.
  • Проверяем собранные вызовы:
    • Заполнено - есть вызовы метода по указанным условиям
    • Пусто - нет вызовов метода по указанным условиям
    • Равно - количество вызовов попавших под условия равно указанному значению
    • Больше - количество вызовов попавших под условия больше указанного значения
    • Меньше - количество вызовов попавших под условия меньше указанного значения

Статистика вызовов

Также вы можете более детально проанализировать вызовы методов

Для этого можно воспользоваться методом Мокито.Проверить(Объект).Вызовы, который возвращает массив с описанием вызовов:

  • Объект - Произвольный - Объект, которому принадлежит метод
  • ИмяМетода - Строка - Имя вызванного метода
  • Параметры - Массив из Произвольный - Набор параметров, с которыми был вызван метод
  • Контекст - Строка - Контекст вызова метода (не реализовано)
ВызовыМетода = Мокито.Проверить(Интеграция).Вызовы("ВыполнитьЗапрос");
ЮТест.ОжидаетЧто(ВызовыМетода, "Вызовы метода ВыполнитьЗапрос")
.ИмеетТип("Массив")
.ИмеетДлину(3)
.КаждыйЭлементСодержитСвойствоСоЗначением("Объект", Интеграция)
.КаждыйЭлементСодержитСвойствоСоЗначением("ИмяМетода", "ВыполнитьЗапрос")
.КаждыйЭлементСодержитСвойство("Параметры")
.Свойство("[0].Параметры[0]").Равно("Адрес")
.Свойство("[1].Параметры[0]").Равно(Адрес)
.Свойство("[2].Параметры[1]").Равно(2);

Примеры

Вызвать исключение при записи объекта

Шаг1. Добавляем метод в расширение

Заимствуем в расширение метод ПередЗаписью, если обработчик в модуле объекта отсутствует вы все равно можете подписаться таким образом на обработку события. И вставляем код для работы Мокито.

&Вместо("ПередЗаписью")
Процедура Мок_ПередЗаписью(Отказ, РежимЗаписи, РежимПроведения)

ПараметрыМетода = Мокито.МассивПараметров(Отказ, РежимЗаписи, РежимПроведения);

ПрерватьВыполнение = Ложь;
МокитоПерехват.АнализВызова(ЭтотОбъект, "ПередЗаписью", ПараметрыМетода, ПрерватьВыполнение);

Если НЕ ПрерватьВыполнение Тогда
ПродолжитьВызов(Отказ, РежимЗаписи, РежимПроведения);
КонецЕсли;

КонецПроцедуры

Шаг2. Настройка теста

После этого вы можете управлять обработкой события в тесте.

Мокито.Обучение(Документы.Оплата)
.Когда("ПередЗаписью").ВыброситьИсключение("Не удалось записать объект")
.Прогон();

Документ = СоздатьДокументОплаты();

ЮТест.ОжидаетЧто(Документ)
.Метод("Записать").Параметр(РежимЗаписиДокумента.Проведение)
.ВыбрасываетИсключение("Не удалось записать объект");
;

Анализ вызовов метода

Предположим у нас есть методы синхронизация данных базы с внешней системой и нам необходимо проверить корректность создания/удаления/изменеиня данных. В общем модуле интеграции созданы методы СоздатьОбъект, УдалитьОбъект, ОбновитьОбъект.

В тесте мы будем формировать различные входные данные и считать вызовы этих методов, проверять чтобы не было лишних вызовов.

Шаг1. Добавление методов в расширение

Сначала необходимо выполнить заимствование и настройку методов СоздатьОбъект, УдалитьОбъект, ОбновитьОбъект.

Шаг2. Настраиваем мокито

Мокито.Обучение(СуперИнтеграция)
.Наблюдать("СоздатьОбъект")
.Наблюдать("УдалитьОбъект")
.Наблюдать("ОбновитьОбъект")
.Прогон();

Шаг3. Реализация теста

ЗаписатьНачальныеДанные(); // Установим начальное состояние базы, создадим нужные данные

// Настроим ответы сервиса, под наши кейсы
Мокито.Обучение(СуперИнтеграция, Ложь) // Важно!. Передаем Ложь, чтобы не затереть ранее установленные настройки
.Когда("ПолучитьДанные")
.Вернуть(ОтветСервисаНовыйЭлемент()) // 1й вызов
.Вернуть(ОтветСервисаИзмененЭлемент()) // 2й вызов
.Вернуть(ОтветСервисаУдаленЭлемент()) // 3й вызов
.Вернуть(ОтветСервисаОшибка()) // 4й вызов
.Вернуть(ОтветСервисаНетДанных()); // 5й вызов

Описание = "Первая итерация, новый элемент";
Мокито.Прогон();
СуперИнтеграция.ВыполнитьСинхронизацию();

Мокито.Проверить(СуперИнтеграция, Описание)
.КоличествоВызовов("СоздатьОбъект").Равно(1)
.КоличествоВызовов("УдалитьОбъект").Пусто()
.КоличествоВызовов("ОбновитьОбъект").Пусто();

Описание = "Вторая итерация, изменен элемент";
Мокито.Прогон(); // Важно!. Повторно вызываем метод, чтобы сбросить ранее накопленную статистику
СуперИнтеграция.ВыполнитьСинхронизацию();

Мокито.Проверить(СуперИнтеграция, Описание)
.КоличествоВызовов("СоздатьОбъект").Пусто()
.КоличествоВызовов("УдалитьОбъект").Пусто()
.КоличествоВызовов("ОбновитьОбъект").Равно(1);

Описание = "Третья итерация, удален элемент";
Мокито.Прогон(); // Важно!. Повторно вызываем метод, чтобы сбросить ранее накопленную статистику
СуперИнтеграция.ВыполнитьСинхронизацию();

Мокито.Проверить(СуперИнтеграция, Описание)
.КоличествоВызовов("СоздатьОбъект").Пусто()
.КоличествоВызовов("УдалитьОбъект").Равно(1)
.КоличествоВызовов("ОбновитьОбъект").Пусто();

// И так далее