Мокирование
Вводная
Мокирование - это инструмент/подход для изоляции тестируемых частей кода и контроля над зависимостями.
При мокировании, мы вместо реальных (продуктовых) объектов подсовываем моки - подделки, фальшивки. Это "двойники" реальных объектов.
Например:
- Вместо, реального почтового сервера мы можем поднять в докере легковесный smtp сервер и настроить систему на взаимодействие с ним
- Используя SOAP UI/Postman/Wiremock или что-то другое мы сможем протестировать систему без использования реального сервиса
- Не редко вместо поднятия промышленной СУБД в тестах используются легковесные встраиваемые СУБД (sql lite, h2)
Все это относится к мокированию и позволяет упростить процесс поднятия окружения для тестов.
Но также моки могут быть использованы непосредственно при тестировании, например вместо реального документа в тестируемый метод вы можете передать структуру, содержащую все нужные реквизиты (Dummy, болванка), либо обработку с нужными методами (Мок), либо что-то иное, что позволяет вам упростить тест.
Например, при тестировании http-сервисов передаем мок, который "притворяется" запросом, реализует интерфейс объекта HTTPСервисЗапрос
.
Основное ограничение такого подхода - обработки и структуры должны передаваться в качестве параметров в тестируемый метод. Если нам очень необходимо подменить объект, который вычисляется внутри метода, то приходится попотеть, либо передавать его в качестве доп. параметров и закладывать работы с ним в конфигурации, либо с помощью расширения возвращать жестко закодированное значение. Каждый раз, в таких случаях, приходится что-то изобретать и выдумывать способ внедрения моков.
Мокито
Для унификации подхода к работе с моками мы разработали инструмент Мокито, который облегчает тестирование.
Он предоставляет
- подход к внедрению моков
- программный интерфейс для управления моками.
Например, у нас есть метод отправки СМС, через шлюз.
Он использует запросы к внешнему ресурсу, СМС шлюзу, который необходим в текущей схеме. Для решения этой проблемы мы можем:
- Отправлять реальные СМС в тестах
- Использовать тестовый шлюза, если провайдер предоставляет такую возможность
- Поднять мокирующий web-server
- Заложить в код обходы для тестирования
- Воспользоваться Мокито, написав в тесте:
Ответ = Новый HTTPСервисОтвет(200);
Ответ.УстановитьТелоИзСтроки(СериализацияJSON.ЗначениеВСтроку(Новый Структура("id, status",
"9999",
"delivered")));
Мокито.Обучение(ОтправкаСМС_Провайдер1)
.Когда("ПослатьСообщение") // Теперь, вместо реального запроса к шлюзу
.Вернуть(Ответ) // метод всегд а будет возвращать нужный нам ответ
.Прогон();
РоботОтправки.ОтправкаСМС();
В это случае, при отправке, не будут выполнятся запросы к шлюзу, вместо этого метод ПослатьСообщение
вернет предопределенный резул ьтат.
Подробнее о возможностях и принципах работы с Мокито, вы можете почитать в отдельной статье.
Моки
Мокито помогает изменять логику работы системы для изоляции тестируемого метода и уменьшения влияния других компонентов системы.
Он закрывает множество задач, но иногда возникают задачи когда даже он не может помочь.
HTTPСервисЗапрос
Первый пример с которым мы столкнулись - тестирование http-сервисов. Сервис на вход принимает объект HTTPСервисЗапрос
, который невозможно создать и настроить из кода 1С.
Необходимо было либо публиковать решение на web-сервере, либо дорабатывать код, чтобы он принимал структуры.
Несколько первых тестов были созданы с помощью структур. Позже возникла идея реализовать мок, который бы походил на HTTPСервисЗапрос
, реализовывал его интерфейс, и который можно настроить из теста.
С ним тестировать сервисы стало намного проще и удобнее, позже его включили в YAxUnit, ЮТест.Данные().HTTPСервисЗапрос
Возможности:
- Реализует методы
HTTPСервисЗапрос
- Свойства
HTTPМетод
\HTTPMethod
БазовыйURL
\BaseURL
Заголовки
\Headers
ОтносительныйURL
\RelativeURL
ПараметрыURL
\URLParameters
ПараметрыЗапроса
\QueryOptions
- Методы
ПолучитьТелоКакДвоичныеДанные()
\GetBodyAsBinaryData()
ПолучитьТелоКакПоток()
\GetBodyAsStream()
ПолучитьТелоКакСтроку()
\GetBodyAsString()
- Свойства
- Имеет методы настройки, реализованные в виде текучих выражений
- Установка тела
УстановитьТелоКакДвоичныеДанные()
УстановитьТелоКакСтроку()
УстановитьТелоКакСтрокуJSON()
- Методы установки свойств
ДобавитьЗаголовок()
ДобавитьПараметрЗапр оса()
ДобавитьПараметрURL()
Метод()
БазовыйURL()
ОтносительныйURL()
- Установка тела
ADO.RecordSet
При тестировании прямых запросов к СУБД также возникает потребность использовать мок, для эмуляции чтения из ADO.RecordSet
.
Для таких кейсов был добавлен ЮТест.Данные().ADORecordSet
реализующий интерфейс ADO.RecordSet
- Свойства
EOF
BOF
AbsolutePosition
RecordCount
Fields
- Методы
MoveFirst()
MoveNext()
Close()
Fields()
EOF()
BOF()
- Методы настройки, реализованные в виде текучих выражений
ЮТест.Данные().ADORecordSet
- принимает информацию о колонкахДобавить()
- добавляет новую строку значений
Создание своих моков
При возникновении подобных ситуаций, когда для тестов вам нужны объекты с какой-то логикой/методами, по аналогии с примерами выше вы без проблем сможете создать нужные вам моки.
Это очень сильно облегчает тестирование и позволяет вам избежать лишнего вмешательства в тестируемый код.