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