1
0
mirror of https://github.com/bia-technologies/yaxunit.git synced 2025-03-17 20:48:01 +02:00

Merge branch 'feature/ORAIS-503' into 'develop'

ORAIS-569 / Мокито для YaxUnit

See merge request orais/ci_cd/yaxunit!6
This commit is contained in:
Максимов Валерий Валерьевич (000044217) 2022-08-08 14:05:23 +03:00
commit f11516694e
35 changed files with 2204 additions and 41 deletions

258
docs/mockito.md Normal file
View File

@ -0,0 +1,258 @@
# Мокито
Мокито - модуль созданный по образу популярного java-фреймворка для тестирования [Mockito](https://site.mockito.org/). Расширяет возможности тестирования, позволяет легко менять логику работы системы подменяя результаты работы методов, отключая какие-либо алгоритмы и проверки.
Юнит-тесты, это тесты конкретных методов в отрыве от системы - контролировать данные используемые методом, изменение логики и ошибки других объектов не должны аффектить на тест.
В реальных конфигурациях объекты тесно связаны друг с другом, поэтому добиться контроля влияющих данных очень сложно. Обычно приходится создавать большой объем тестовых данных. А добиться изоляции от изменения логики других объектов почти невозможно. Мокирование же позволяет изменить логику работы системы таким образом, чтобы тестируемый метод не вызывал другие методы и использовал уже подготовленные данные. Например, для тестирования проведения реализации товаров мы можем подменить результат функции формирующей таблицу проводок и избежать сложной подготовки данных.
С помощью Мокито разработчик указывает, что делать при вызове определенных методов - вернуть нужный результат, вызвать исключение или просто не трогать ненужные методы. После тестирования разработчик может запросить и проверить статистику о вызовах, как и какие методы были вызваны.
Пример:
```bsl
ОтветСерверы = ОтветУспешногоЗапроса("Серверы");
ОтветДиски = ОтветУспешногоЗапроса("Диски");
Мокито.Обучение(РаботаСHTTP)
.Когда(РаботаСHTTP.ВыполнитьЗапрос(ПараметрыПодключения, "/hosts", "GET"))
.Вернуть(ОтветСерверы)
.Когда(РаботаСHTTP.ВыполнитьЗапрос(ПараметрыПодключения, "/disks", "GET"))
.Вернуть(ОтветДиски)
.Прогон();
Результат = БиллингДрайверГипервизорNutanix.Серверы(ПараметрыПодключения);
```
В этом примере изменяется работа модуля `РаботаСHTTP`, для функции `ВыполнитьЗапрос`, вызванной с нужными параметрами будет возвращено подготовленное значение, а сам метод не будет вызван.
Мы получим ожидаемые ответы на запросы к сторонней системе и уйдет от проблем связанных с ней - недоступность, изменение контрактов и т.д.
Работа с Мокито делится на 3 стадии:
1. Обучение - настраиваем поведение методов системы
2. Прогон - выполнение теста целевого метода
3. Проверка - анализ вызовов
## Использование
### Настройка мокируемых методов
Для работы Мокито вам необходимо добавить интересующие методы в тестовое расширение.
Эта позволит управлять поведением метода:
* подменять результат во время выполнения теста
* использовать явный вызов метода с параметрами на стадии обучения, например `Мокито.Обучение(Справочники.ИсточникиДанных).Когда(Справочники.ИсточникиДанных.СохраненныеБезопасныеДанные(Справочник)).Вернуть(Результат)`
* использовать явный вызов метода с параметрами на стадии проверки, например `Мокито.Проверить(Справочники.ИсточникиДанных).КоличествоВызовов(Справочники.ИсточникиДанных.СохраненныеБезопасныеДанные(Справочник)).Больше(1)`
Примеры добавления методов в расширение:
#### Метод общего модуля
Добавляем обработку метода `ИнициализироватьВнешнююКомпоненту` общего модуля `ОбщегоНазначенияКлиентСервер`
```bsl
&Вместо("ИнициализироватьВнешнююКомпоненту")
Функция ЮТИнициализироватьВнешнююКомпоненту(ИмяМакета, ИмяКомпоненты, ВызыватьИсключение, ПаузаЧерезКомпоненту) Экспорт
// Собираем параметры в массив
ПараметрыМетода = Мокито.МассивПараметров(ИмяМакета, ИмяКомпоненты, ВызыватьИсключение, ПаузаЧерезКомпоненту);
// Отправляем данные на анализ
ПрерватьВыполнение = Ложь;
Результат = Мокито.АнализВызова(ОбщегоНазначенияКлиентСервер, "ИнициализироватьВнешнююКомпоненту", ПараметрыМетода, ПрерватьВыполнение);
// Обрабатываем результат анализа
Если НЕ ПрерватьВыполнение Тогда
Возврат ПродолжитьВызов(ИмяМакета, ИмяКомпоненты, ВызыватьИсключение, ПаузаЧерезКомпоненту);
Иначе
Возврат Результат;
КонецЕсли;
КонецФункции
```
#### Метод модуля менеджера
Добавляем обработку метода `СохраненныеБезопасныеДанные` модуля менеджера справочника `Справочники.ИсточникиДанных`
```bsl
&Вместо("СохраненныеБезопасныеДанные")
Функция ЮТСохраненныеБезопасныеДанные(Владелец, Знач Ключи) Экспорт
// Собираем параметры в массив
ПараметрыМетода = Мокито.МассивПараметров(Владелец, Ключи);
// Отправляем данные на анализ
ПрерватьВыполнение = Ложь;
Результат = Мокито.АнализВызова(Справочники.ИсточникиДанных, "СохраненныеБезопасныеДанные", ПараметрыМетода, ПрерватьВыполнение);
// Обрабатываем результат анализа
Если НЕ ПрерватьВыполнение Тогда
Возврат ПродолжитьВызов(Владелец, Ключи);
Иначе
Возврат Результат;
КонецЕсли;
КонецФункции
```
#### Метод модуля объекта
Добавляем обработку приватного метода `ПеренестиДанныеВБезопасноеХранилище` модуля объекта справочника `Справочники.ИсточникиДанных`
```bsl
&Вместо("ПеренестиДанныеВБезопасноеХранилище")
Функция ЮТПеренестиДанныеВБезопасноеХранилище(Ключи)
// Собираем параметры в массив
ПараметрыМетода = Мокито.МассивПараметров(Ключи);
// Отправляем данные на анализ
ПрерватьВыполнение = Ложь;
Результат = Мокито.АнализВызова(ЭтотОбъект, "ПеренестиДанныеВБезопасноеХранилище", ПараметрыМетода, ПрерватьВыполнение);
// Обрабатываем результат анализа
Если НЕ ПрерватьВыполнение Тогда
Возврат ПродолжитьВызов(Ключи);
Иначе
Возврат Результат;
КонецЕсли;
КонецФункции
```
### Обучение
Самая первая стадия при написании тестов использующих моки - обучение.
Мы создаем правила как будет вести себя метод при различных вариантах вызова.
Правило состоит из условий проверки параметров и действия выполняемого при соблюдении условий.
Условия можно задать на равенство определенному значению, на проверку типа переданного значения или же безусловно принимать любый параметры
Существует 2 основных подхода к формированию условий вызова:
1. Явный вызов метода с параметрами: `Обучение(РаботаСHTTP).Когда(РаботаСHTTP.ОтправитьОбъектНаСервер(ИсточникДанных, Данные)).Вернуть(2)`
2. Указание имени метода и набора параметров: `Обучение(РаботаСHTTP).Когда("ОтправитьОбъектНаСервер", Мокито.МассивПараметров(ИсточникДанных, Данные)).Вернуть(2)`
Первый вариант имеет ряд недостатков:
1. Работает только для экспортных методов
2. Необходимо передавать все обязательные параметры или использовать для них маску `Мокито.ЛюбойПараметр()`
3. Если не указывать необязательные параметры, то их значения по умолчанию попадут в настройку. Покажу на примере.
Имеется метод `Функция Метод(Параметр1, Параметр2, Параметр3 = 3)`
Настройка `Когда(Метод(1, 2)).Вернуть(0)`, в результате ноль мы получим для вызовов
* `Метод(1, 2)`
* `Метод(1, 2, 3)`
Для вызова `Метод(1, 2, 4)` будет выполнен основной алгоритм метода.
А для настройки `Когда("Метод", Мокито.МассивПараметров(1, 2)).Вернуть(0)` все три варианта вызова вернут ноль.
После того как определились с условием вызова указанным в методе `Когда` нужно указать реакцию. Возможные реакции:
* `Вернуть` - вернуть указанное значение
* `ВыброситьИсключение` - вызвать исключение с переданным текстом
* `Пропустить` - пропустить выполнение метод (актуально для процедур)
#### Примеры формирования различных вариантов условий
Имеется метод:
```bsl
Функция ОтправитьОбъектНаСервер(ИсточникДанных, Объект, HTTPМетод = "POST",
ТипКонтента = "json", Преобразование = Неопределено,
ДопНастройки = Неопределено, Ответ = Неопределено, ОтветВСтруктуру = Ложь,
ТелоОтветаВХранилище = Ложь) Экспорт
```
* Переопределить все вызовы метода - указываем имя метода без указания параметров
`Мокито.Обучение(РаботаСHTTP).Когда("ОтправитьОбъектНаСервер").Вернуть(1)`
* Переопределить вызов, когда первый параметр имеет определенное значение
1. `Мокито.Обучение(РаботаСHTTP).Когда("ОтправитьОбъектНаСервер", Мокито.МассивПараметров(ИсточникДанных)).Вернуть(2)`
2. `Мокито.Обучение(РаботаСHTTP).Когда(РаботаСHTTP.ОтправитьОбъектНаСервер(ИсточникДанных, Мокито.ЛюбойПараметр()).Вернуть(2)`. Тут используется маска `Мокито.ЛюбойПараметр()`, тк второй параметр является обязательным
* Переопределить вызов, когда **второй** параметр имеет определенное значение
1. `Мокито.Обучение(РаботаСHTTP).Когда("ОтправитьОбъектНаСервер", Мокито.МассивПараметров(Мокито.ЛюбойПараметр(), Объект)).Вернуть(2)`
2. `Мокито.Обучение(РаботаСHTTP).Когда(РаботаСHTTP.ОтправитьОбъектНаСервер(Мокито.ЛюбойПараметр(), Объект).Вернуть(2)`.
* Условие на тип параметра
1. `Мокито.Обучение(РаботаСHTTP).Когда("ОтправитьОбъектНаСервер", Мокито.МассивПараметров(Мокито.ТипизированныйПараметр(ТипИсточникДанных), Мокито.ЧисловойПараметр())).Вернуть(3)`
2. `Мокито.Обучение(РаботаСHTTP).Когда(РаботаСHTTP.ОтправитьОбъектНаСервер(Мокито.ТипизированныйПараметр(ТипИсточникДанных), Мокито.ЧисловойПараметр()).Вернуть(3)`
## Прогон
После обучения, настройки реакций на вызовы методов, можно запускать тест нужного метода. Для перехода к этому режиму работы Мокито используется метод `Прогон`.
Все вызовы к настроенным методам (добавленным в расширение) будут перехватываться и анализироваться на совпадение условий вызова.
Для вызовов, у которых есть подходящая "реакция" будет переопределено выполнение и запустится соответствующая реакция (вернуть значение, вызвать исключение и тд), для прочих - выполнение продолжится.
```bsl
// Настройка
Мокито.Обучение(РаботаСHTTP)
.Когда("ОтправитьОбъектНаСервер", Мокито.МассивПараметров(Мокито.ЛюбойПараметр(), Мокито.ЛюбойПараметр()))
.Вернуть(РезультатПоУмолчанию)
.Когда("ОтправитьОбъектНаСервер", Мокито.МассивПараметров(Справочники.ИсточникиДанных.FTP, 2))
.Вернуть(2)
.Прогон(); // Перевод в режим прогона теста
Результат = РаботаСHTTP.ОтправитьОбъектНаСервер(ИсточникДанных, Данные); // Результат будет равен переменной РезультатПоУмолчанию
Результат = РаботаСHTTP.ОтправитьОбъектНаСервер(Справочники.ИсточникиДанных.FTP, 2); // Результат будет равен 2
```
## Проверка
После прогона теста можно проверить какие методы, с какими параметрами вызывались. Для этих целей необходимо воспользоваться методом `Проверить`
```bsl
Мокито.Проверить(РаботаСHTTP) // Устанавливаем проверяемый объект
.КоличествоВызовов(РаботаСHTTP.ОтправитьОбъектНаСервер(ЛюбойПараметр, Мокито.ЧисловойПараметр())) // Условия поиска вызовов
.Больше(1) // Проверки
.Равно(2)
.КоличествоВызовов("ОтправитьОбъектНаСервер").Заполнено().Равно(3).Меньше(6)
.КоличествоВызовов("ОтправитьЗапросHTTP").Пусто().Меньше(1)
.КоличествоВызовов(РаботаСHTTP.ОтправитьОбъектНаСервер(1, 2)).Равно(1)
.КоличествоВызовов(РаботаСHTTP.ОтправитьОбъектНаСервер(ЛюбойПараметр, ЛюбойПараметр)).Равно(3)
.КоличествоВызовов(РаботаСHTTP.ОтправитьОбъектНаСервер(Мокито.ТипизированныйПараметр(ТипИсточникДанных), ЛюбойПараметр)).Равно(1)
```
Принцип формирования проверки:
* Указываем проверяемый объект `Проверить(РаботаСHTTP)`.
* Указываем условия поиска вызовов метода. Логика формирования условия такая же как при обучении.
Например, `КоличествоВызовов(РаботаСHTTP.ОтправитьОбъектНаСервер(ЛюбойПараметр, Мокито.ЧисловойПараметр()))`
Соберет все вызовы метода `РаботаСHTTP.ОтправитьОбъектНаСервер`, к которых вторым параметром идет число, а 3й и последующий параметры имеют значения по умолчанию.
* Проверяем собранные вызовы:
* `Заполнено` - есть вызовы метода по указанным условиям
* `Пусто` - нет вызовов метода по указанным условиям
* `Равно` - количество вызовов попавших под условия равно указанному значению
* `Больше` - количество вызовов попавших под условия больше указанного значения
* `Меньше` - количество вызовов попавших под условия меньше указанного значения
## Кейсы использования\*
\* *В примерах опускается часть добавления метода в расширение*
1. Подмена результат функции для любого вызова
```bsl
Мокито.Обучение(РаботаСHTTP)
.Когда("ОтправитьОбъектНаСервер")
.Вернуть(1)
```
2. Выключение алгоритма проведения документа
```bsl
Мокито.Обучение(СсылкаИлиОбъектДокумент)
.Когда("ОбработкаПроведения")
.Пропустить()
```
3. Выбросить исключение, если в метод передан некорректный набор параметров
```bsl
Мокито.Обучение(РаботаСHTTP)
.Когда("ОтправитьОбъектНаСервер")
.ВыброситьИсключение("Не верные параметры вызова")
.Когда(РаботаСHTTP.ОтправитьОбъектНаСервер(Справочники.ИсточникиДанных.FTP, Мокито.ЛюбойПараметр()))
.ВыполнитьМетод();
```

View File

@ -1,3 +1,3 @@
Manifest-Version: 1.0
Runtime-Version: 8.3.10
Base-Project: configuration
Base-Project: BSP

View File

@ -0,0 +1,33 @@
//©///////////////////////////////////////////////////////////////////////////©//
//
// Copyright 2021-2022 BIA-Technologies Limited Liability Company
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
//©///////////////////////////////////////////////////////////////////////////©//
&Вместо("ПолучитьСтруктуруИзХранилища")
Функция ЮТПолучитьСтруктуруИзХранилища() Экспорт
ПараметрыМетода = Новый Массив();;
ПрерватьВыполнение = Ложь;
Результат = Мокито.АнализВызова(ЭтотОбъект, "ПолучитьСтруктуруИзХранилища", ПараметрыМетода, ПрерватьВыполнение);
Если НЕ ПрерватьВыполнение Тогда
Возврат ПродолжитьВызов();
Иначе
Возврат Результат;
КонецЕсли;
КонецФункции

View File

@ -0,0 +1,15 @@
<?xml version="1.0" encoding="UTF-8"?>
<mdclass:Catalog xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:mdclass="http://g5.1c.ru/v8/dt/metadata/mdclass" xmlns:mdclassExtension="http://g5.1c.ru/v8/dt/metadata/mdclass/extension" uuid="b6940270-fdf2-4e08-bece-d98e824d5b50">
<producedTypes>
<objectType typeId="d5bf9fd0-e2a2-4d32-9a09-b09e484f8198" valueTypeId="3d5cc1d2-0173-4750-9f8e-c0643618c079"/>
<refType typeId="dbfce91a-b175-43ee-a319-075bc6f511bc" valueTypeId="b667772d-0cdc-4ee6-8a44-831c0d1ea0a8"/>
<selectionType typeId="a7ca7180-81e7-4297-9209-0f553d482249" valueTypeId="0cfb7d72-9e2c-4d20-8683-684a5ecb331f"/>
<listType typeId="930bcca4-65ad-4b49-a81b-e6b57e31f324" valueTypeId="3d1b05cd-b8c8-4888-bde0-71a73afc0d65"/>
<managerType typeId="4c3f8f0c-daf7-49e7-94c9-a0ac9bce6511" valueTypeId="a279f0c0-adeb-433d-b9a6-cbfc500b11b1"/>
</producedTypes>
<name>ДополнительныеПараметрыЖурналаДействийПользователя</name>
<objectBelonging>Adopted</objectBelonging>
<extension xsi:type="mdclassExtension:CatalogExtension">
<objectModule>Extended</objectModule>
</extension>
</mdclass:Catalog>

View File

@ -0,0 +1,40 @@
//©///////////////////////////////////////////////////////////////////////////©//
//
// Copyright 2021-2022 BIA-Technologies Limited Liability Company
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
//©///////////////////////////////////////////////////////////////////////////©//
#Если НЕ (ТонкийКлиент ИЛИ ВебКлиент) Тогда
&Вместо("СохраненныеБезопасныеДанные")
Функция ЮТСохраненныеБезопасныеДанные(Владелец, Знач Ключи) Экспорт
// Собираем параметры в массив
ПараметрыМетода = Мокито.МассивПараметров(Владелец, Ключи);
// Отправляем данные на анализ
ПрерватьВыполнение = Ложь;
Результат = Мокито.АнализВызова(Справочники.ИсточникиДанных, "СохраненныеБезопасныеДанные", ПараметрыМетода, ПрерватьВыполнение);
// Обрабатываем результат анализа
Если НЕ ПрерватьВыполнение Тогда
Возврат ПродолжитьВызов(Владелец, Ключи);
Иначе
Возврат Результат;
КонецЕсли;
КонецФункции
#КонецЕсли

View File

@ -0,0 +1,31 @@
//©///////////////////////////////////////////////////////////////////////////©//
//
// Copyright 2021-2022 BIA-Technologies Limited Liability Company
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
//©///////////////////////////////////////////////////////////////////////////©//
&Вместо("ПеренестиДанныеВБезопасноеХранилище")
Процедура ЮТПеренестиДанныеВБезопасноеХранилище()
ПараметрыМетода = Новый Массив;
ПрерватьВыполнение = Ложь;
Мокито.АнализВызова(ЭтотОбъект, "ПеренестиДанныеВБезопасноеХранилище", ПараметрыМетода, ПрерватьВыполнение);
Если НЕ ПрерватьВыполнение Тогда
ПродолжитьВызов();
КонецЕсли;
КонецПроцедуры

View File

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<mdclass:Catalog xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:mdclass="http://g5.1c.ru/v8/dt/metadata/mdclass" xmlns:mdclassExtension="http://g5.1c.ru/v8/dt/metadata/mdclass/extension" uuid="12d39ba3-2aff-4422-b24e-36d437cf038e">
<producedTypes>
<objectType typeId="a1b9e06e-d148-4bf2-a5ce-9ffd250dfb0e" valueTypeId="7ccfc536-9646-4766-92bd-1d0f65d793be"/>
<refType typeId="b1e6dc87-a5fb-44f4-9372-54aa019aeefa" valueTypeId="f6fe9c2f-f0ba-4d4c-97e4-ca8ff4204f9c"/>
<selectionType typeId="ac18a9d7-cac3-4095-b27a-4ff50ae53820" valueTypeId="f1d2485d-64b9-4208-9749-393b4dea43bf"/>
<listType typeId="b8e1e31b-8c4e-4c33-9a54-c57f03674645" valueTypeId="39a86771-483a-4271-bae1-ee735b402237"/>
<managerType typeId="735d6743-f53b-4790-ac85-526b24fb3d2d" valueTypeId="fd5882d3-d390-4de7-a23c-bc227beef791"/>
</producedTypes>
<name>ИсточникиДанных</name>
<objectBelonging>Adopted</objectBelonging>
<extension xsi:type="mdclassExtension:CatalogExtension">
<objectModule>Extended</objectModule>
<managerModule>Extended</managerModule>
</extension>
</mdclass:Catalog>

View File

@ -0,0 +1,181 @@
//©///////////////////////////////////////////////////////////////////////////©//
//
// Copyright 2021-2022 BIA-Technologies Limited Liability Company
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
//©///////////////////////////////////////////////////////////////////////////©//
///////////////////////////////////////////////////////////////////
// ПрограммныйИнтерфейс
// Экспортные процедуры и функции для прикладного использования
///////////////////////////////////////////////////////////////////
#Область ПрограммныйИнтерфейс
// Обучение.
// Начинает обучение мокито для регистрации правил подмены вызовов методов
//
// Параметры:
// Объект - Произвольный - Объект, методы которого хотим подменить
//
// Возвращаемое значение:
// ОбщийМодуль
// Пример:
// Для работы Мокито необходимо добавить обрабатываемые методы в расширение по следующей схеме
//
// &Вместо("ВыполнитьЗапрос")
// Функция ЮТВыполнитьЗапрос(ПараметрыПодключения, Ресурс, HTTPМетод, Параметры, ОписаниеТела, Заголовки) Экспорт
//
// ПараметрыМетода = Мокито.МассивПараметров(ПараметрыПодключения, Ресурс, HTTPМетод, Параметры, ОписаниеТела, Заголовки);
//
// ПрерватьВыполнение = Ложь;
// Результат = Мокито.АнализВызова(РаботаСHTTP, "ВыполнитьЗапрос", ПараметрыМетода, ПрерватьВыполнение);
//
// Если НЕ ПрерватьВыполнение Тогда
// Возврат ПродолжитьВызов(ПараметрыПодключения, Ресурс, HTTPМетод, Параметры, ОписаниеТела, Заголовки);
// Иначе
// Возврат Результат;
// КонецЕсли;
//
// КонецФункции
Функция Обучение(Объект) Экспорт
Режимы = МокитоСлужебный.РежимыРаботы();
МокитоСлужебный.УстановитьРежим(Режимы.Обучение);
Возврат МокитоОбучение.Обучение(Объект);
КонецФункции
// Прогон
// Переводит мокито в режим прогона тестов
// Вызов этого метода обязателен перед выполнением тестового прогона метода
Процедура Прогон() Экспорт
Режимы = МокитоСлужебный.РежимыРаботы();
МокитоСлужебный.УстановитьРежим(Режимы.Тестирование);
КонецПроцедуры
// Проверить.
// Переводит мокито в режим проверки вызовов
// Параметры:
// Объект - Произвольный - Устанавливает проверяемый объект, вызовы методов которого будем проверять
//
// Возвращаемое значение:
// ОбщийМодуль
Функция Проверить(Объект) Экспорт
Режимы = МокитоСлужебный.РежимыРаботы();
МокитоСлужебный.УстановитьРежим(Режимы.Проверка);
Возврат МокитоПроверки.Проверить(Объект);
КонецФункции
// Сбросить
// Сбрасывает настройки, переинициализирует мокито
Процедура Сбросить() Экспорт
МокитоСлужебный.СброситьПараметры();
КонецПроцедуры
#Область КонструкторыПараметров
// Любой параметр.
// Возвращает маску параметра. Используется при обучении и проверках для фильтрации входных параметров метода
// Указывает, что в метод может передаваться любой параметр
// Возвращаемое значение:
// см. МокитоСлужебный.ОписаниеМаскиПараметра
Функция ЛюбойПараметр() Экспорт
МаскаПараметра = МокитоСлужебный.ОписаниеМаскиПараметра(МокитоСлужебный.ТипыУсловийПараметров().Любой, 0);
Возврат МаскаПараметра;
КонецФункции
// Числовой параметр.
// Возвращает маску параметра. Используется при обучении и проверках для фильтрации входных параметров метода
// Указывает, что в метод может передаваться числовой параметр
// Возвращаемое значение:
// см. Мокито.ТипизированныйПараметр
Функция ЧисловойПараметр() Экспорт
Возврат ТипизированныйПараметр(Тип("Число"));
КонецФункции
// Строковый параметр.
// Возвращает маску параметра. Используется при обучении и проверках для фильтрации входных параметров метода
// Указывает, что в метод может передаваться строковый параметр
// Возвращаемое значение:
// см. Мокито.ТипизированныйПараметр
Функция СтроковыйПараметр() Экспорт
Возврат ТипизированныйПараметр(Тип("Строка"));
КонецФункции
// Типизированный параметр.
// Возвращает маску параметра. Используется при обучении и проверках для фильтрации входных параметров метода
// Указывает, что в метод может передаваться параметр указанного типа
//
// Параметры:
// Тип - Тип - Ограничение типа параметра
//
// Возвращаемое значение:
// см. МокитоСлужебный.ОписаниеМаскиПараметра
Функция ТипизированныйПараметр(Тип) Экспорт
МаскаПараметра = МокитоСлужебный.ОписаниеМаскиПараметра(МокитоСлужебный.ТипыУсловийПараметров().Тип, 1);
МаскаПараметра.Вставить("Тип", Тип);
Возврат МаскаПараметра;
КонецФункции
Функция МассивПараметров(Параметр1 = "_!%*",
Параметр2 = "_!%*",
Параметр3 = "_!%*",
Параметр4 = "_!%*",
Параметр5 = "_!%*",
Параметр6 = "_!%*",
Параметр7 = "_!%*",
Параметр8 = "_!%*",
Параметр9 = "_!%*",
Параметр10 = "_!%*") Экспорт
Возврат МокитоСлужебный.МассивПараметров(Параметр1,
Параметр2,
Параметр3,
Параметр4,
Параметр5,
Параметр6,
Параметр7,
Параметр8,
Параметр9,
Параметр10);
КонецФункции
#КонецОбласти
Функция АнализВызова(Объект, ИмяМетода, ПараметрыМетода, ПрерватьВыполнение) Экспорт
Возврат МокитоСлужебный.АнализВызова(Объект, ИмяМетода, ПараметрыМетода, ПрерватьВыполнение);
КонецФункции
#КонецОбласти

View File

@ -1,9 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<mdclass:CommonModule xmlns:mdclass="http://g5.1c.ru/v8/dt/metadata/mdclass" uuid="645d86e0-f482-471a-b261-fa1811f533cb">
<name>ОМ_ЮТ</name>
<mdclass:CommonModule xmlns:mdclass="http://g5.1c.ru/v8/dt/metadata/mdclass" uuid="b5c40903-c446-420c-824e-07c58f5b7021">
<name>Мокито</name>
<synonym>
<key>ru</key>
<value>ЮТ</value>
<value>Мокито</value>
</synonym>
<clientManagedApplication>true</clientManagedApplication>
<server>true</server>
<clientOrdinaryApplication>true</clientOrdinaryApplication>
</mdclass:CommonModule>

View File

@ -0,0 +1,276 @@
//©///////////////////////////////////////////////////////////////////////////©//
//
// Copyright 2021-2022 BIA-Technologies Limited Liability Company
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
//©///////////////////////////////////////////////////////////////////////////©//
///////////////////////////////////////////////////////////////////
// ПрограммныйИнтерфейс
// Экспортные процедуры и функции для прикладного использования
///////////////////////////////////////////////////////////////////
#Область ПрограммныйИнтерфейс
// Обучение.
// Начинает обучение мокито для регистрации правил подмены вызовов методов
//
// Параметры:
// Объект - Произвольный - Объект, методы которого хотим подменить
//
// Возвращаемое значение:
// ОбщийМодуль
Функция Обучение(Объект) Экспорт
УстановитьПараметрыОбучения(Объект);
Возврат МокитоОбучение;
КонецФункции
// Наблюдать.
//
// Параметры:
// ИмяМетода - Строка - Имя метода обучаемого объекта
// - Произвольный - Вызов метода обучаемого объекта
// ПараметрыВызова - Массив из Произвольный - Параметры вызова метода обучаемого объекта
// Варианты вызова:
// Мокито.Обучение(Произвольный).Когда(Строка, Массив); // Вызов через указание имени метода и параметров
// Мокито.Обучение(Произвольный).Когда(Произвольный); // Вызов через явное выполнение наблюдаемого метода
//
// Возвращаемое значение:
// ОбщийМодуль
// Пример:
// Мокито.Обучение(ОбщегоНазначения).Наблюдать("ЭтоДопустимоеИмяПеременной", Мокито.МассивПараметров(""));
// Мокито.Обучение(ОбщегоНазначения).Наблюдать(ОбщегоНазначения.ЭтоДопустимоеИмяПеременной(""));
Функция Наблюдать(ИмяМетода, ПараметрыВызова = Неопределено) Экспорт
ЗарегистрироватьПерехватВыражения(ИмяМетода, ПараметрыВызова);
Возврат МокитоОбучение;
КонецФункции
// Когда.
//
// Параметры:
// ИмяМетода - Строка - Имя метода обучаемого объекта
// - Произвольный - Вызов метода обучаемого объекта
// ПараметрыВызова - Массив из Произвольный - Параметры вызова метода обучаемого объекта
// Варианты вызова:
// Мокито.Обучение(Произвольный).Когда(Строка, Массив); // Вызов через указание имени метода и параметров
// Мокито.Обучение(Произвольный).Когда(Произвольный); // Вызов через явное выполнение наблюдаемого метода
//
// Возвращаемое значение:
// ОбщийМодуль
// Пример:
// Мокито.Обучение(ОбщегоНазначения).Когда("ЭтоДопустимоеИмяПеременной", Мокито.МассивПараметров(""));
// Мокито.Обучение(ОбщегоНазначения).Когда(ОбщегоНазначения.ЭтоДопустимоеИмяПеременной(""));
Функция Когда(ИмяМетода, ПараметрыВызова = Неопределено) Экспорт
Возврат Наблюдать(ИмяМетода, ПараметрыВызова);
КонецФункции
// Вернуть.
// Указывает, что при соблюдении условий метод должен вернуть переданное значение
// Параметры:
// Результат - Произвольный - Результат, который должен вернуть метод
//
// Возвращаемое значение:
// ОбщийМодуль
Функция Вернуть(Результат) Экспорт
ЗарегистрироватьРеакцию(Новый Структура("ТипДействия, Результат", МокитоСлужебный.ТипыДействийРеакций().ВернутьРезультат, Результат));
Возврат МокитоОбучение;
КонецФункции
// Выбросить исключение.
// Указывает, что при соблюдении условий метод должен выбросить исключение
//
// Параметры:
// ТекстИсключения - Строка
//
// Возвращаемое значение:
// ОбщийМодуль
Функция ВыброситьИсключение(ТекстИсключения) Экспорт
ЗарегистрироватьРеакцию(Новый Структура("ТипДействия, Ошибка", МокитоСлужебный.ТипыДействийРеакций().ВыброситьИсключение, ТекстИсключения));
Возврат МокитоОбучение;
КонецФункции
// Пропустить.
// Указывает, что при соблюдении условий метод не должен выполняться, его вызов пропускается
//
// Возвращаемое значение:
// ОбщийМодуль
Функция Пропустить() Экспорт
ЗарегистрироватьРеакцию(Новый Структура("ТипДействия", МокитоСлужебный.ТипыДействийРеакций().Пропустить));
Возврат МокитоОбучение;
КонецФункции
// Выполнить метод.
// Указывает, что при соблюдении условий метод должен выполняться
//
// Возвращаемое значение:
// ОбщийМодуль
Функция ВыполнитьМетод() Экспорт
ЗарегистрироватьРеакцию(Новый Структура("ТипДействия", МокитоСлужебный.ТипыДействийРеакций().ВызватьОсновнойМетод));
Возврат МокитоОбучение;
КонецФункции
// Прогон
// Переводит мокито в режим прогона тестов
// Вызов этого метода обязателен перед выполнением тестового прогона метода
Процедура Прогон() Экспорт
Мокито.Прогон();
КонецПроцедуры
#КонецОбласти
/////////////////////////////////////////////////////////////////////////////////
// Экспортные процедуры и функции для служебного использования внутри подсистемы
/////////////////////////////////////////////////////////////////////////////////
#Область СлужебныйПрограммныйИнтерфейс
#КонецОбласти
/////////////////////////////////////////////////////////////////////////////////
// Процедуры и функции, составляющие внутреннюю реализацию модуля
/////////////////////////////////////////////////////////////////////////////////
#Область СлужебныеПроцедурыИФункции
Процедура ЗарегистрироватьПерехватВыражения(ИмяМетода, ПараметрыВызова)
Объект = ОбучаемыйОбъект();
ДанныеПерехвата = МокитоСлужебный.ДанныеПерехвата(Объект);
Если ДанныеПерехвата = Неопределено Тогда
Сообщение = СтрШаблон("Не найдены настройки перехвата для %1. Необходимо предварительно вызвать метод Мокито.Обучение(Объект)", Объект);
ВызватьИсключение Сообщение;
КонецЕсли;
Если МокитоСлужебный.ЭтоСтруктураВызоваМетода(ИмяМетода) Тогда
СтруктураВызоваМетода = ИмяМетода;
Иначе
СтруктураВызоваМетода = МокитоСлужебный.СтруктураВызоваМетода(Объект, ИмяМетода, ПараметрыВызова);
КонецЕсли;
Методы = ДанныеПерехвата.Методы;
Если НЕ Методы.Свойство(СтруктураВызоваМетода.ИмяМетода) Тогда
Методы.Вставить(СтруктураВызоваМетода.ИмяМетода, ОписаниеПараметровПерехватаМетода());
КонецЕсли;
Реакция = СоздатьОписаниеУсловнойРеакции(СтруктураВызоваМетода);
Методы[СтруктураВызоваМетода.ИмяМетода].Реакции.Добавить(Реакция);
ПараметрыОбучения().РеакцияТекущегоВыражения = Реакция;
КонецПроцедуры
Функция ОписаниеПараметровПерехватаМетода()
Возврат Новый Структура("Реакции", Новый Массив);
КонецФункции
#Область Реакции
Функция СоздатьОписаниеУсловнойРеакции(СтруктураВызоваМетода)
Возврат Новый Структура("УсловиеРеакции, Действие", УсловиеРеакции(СтруктураВызоваМетода), Неопределено);
КонецФункции
Функция УсловиеРеакции(СтруктураВызоваМетода)
Параметры = СтруктураВызоваМетода.Параметры;
Если Параметры = Неопределено Тогда
Возврат Неопределено;
КонецЕсли;
Условия = Новый Массив;
Для Каждого Параметр Из Параметры Цикл
Если МокитоСлужебный.ЭтоМаскаПарамера(Параметр) Тогда
Условия.Добавить(Параметр);
Иначе
Условия.Добавить(Новый Структура("Режим, Значение, Приоритет", "Значение", Параметр, 10));
КонецЕсли;
КонецЦикла;
Возврат Условия;
КонецФункции
#КонецОбласти
#Область Параметры
Функция ОбучаемыйОбъект()
ПараметрыОбучения = ПараметрыОбучения();
Возврат ПараметрыОбучения.ОбучаемыйОбъект;
КонецФункции
Функция ПараметрыОбучения()
Параметры = МокитоСлужебный.Настройки().ПараметрыОбучения;
Возврат Параметры;
КонецФункции
Процедура УстановитьПараметрыОбучения(Объект)
ПараметрыОбучения = Новый Структура("ОбучаемыйОбъект, РеакцияТекущегоВыражения", Объект, Неопределено);
МокитоСлужебный.Настройки().ПараметрыОбучения = ПараметрыОбучения;
МокитоСлужебный.ЗарегистрироватьПерехватОбъекта(Объект);
КонецПроцедуры
Процедура ЗарегистрироватьРеакцию(Действие)
Действие.Вставить("Обработано", Ложь);
ПараметрыОбучения().РеакцияТекущегоВыражения.Действие = Действие;
КонецПроцедуры
#КонецОбласти
#КонецОбласти

View File

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<mdclass:CommonModule xmlns:mdclass="http://g5.1c.ru/v8/dt/metadata/mdclass" uuid="e25ecfb4-02ca-4764-84e7-dfc8cdaa02dc">
<name>МокитоОбучение</name>
<synonym>
<key>ru</key>
<value>Мокито обучение</value>
</synonym>
<clientManagedApplication>true</clientManagedApplication>
<server>true</server>
<clientOrdinaryApplication>true</clientOrdinaryApplication>
</mdclass:CommonModule>

View File

@ -0,0 +1,272 @@
//©///////////////////////////////////////////////////////////////////////////©//
//
// Copyright 2021-2022 BIA-Technologies Limited Liability Company
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
//©///////////////////////////////////////////////////////////////////////////©//
///////////////////////////////////////////////////////////////////
// ПрограммныйИнтерфейс
// Экспортные процедуры и функции для прикладного использования
///////////////////////////////////////////////////////////////////
#Область ПрограммныйИнтерфейс
// Проверить.
// Переводит мокито в режим проверки вызовов
// Параметры:
// Объект - Произвольный - Устанавливает проверяемый объект, вызовы методов которого будем проверять
//
// Возвращаемое значение:
// ОбщийМодуль
Функция Проверить(Объект) Экспорт
УстановитьПараметрыПроверки(Объект);
Возврат МокитоПроверки;
КонецФункции
// Количество вызовов.
// Считает вызовы метода по переданным параметрам
// Параметры:
// ИмяМетода - Строка - Имя метода проверяемого объекта
// - Произвольный - Вызов метода проверяемого объекта
// ПараметрыВызова - Массив из Произвольный - Параметры вызова метода проверяемого объекта, необходим при указании имени метода
// Возвращаемое значение:
// ОбщийМодуль
Функция КоличествоВызовов(ИмяМетода = Неопределено, ПараметрыВызова = Неопределено) Экспорт
Параметры = ПараметрыПроверки();
Если МокитоСлужебный.ЭтоСтруктураВызоваМетода(ИмяМетода) Тогда
СтруктураВызоваМетода = ИмяМетода;
Иначе
СтруктураВызоваМетода = МокитоСлужебный.СтруктураВызоваМетода(Параметры.ПроверяемыйОбъект, ИмяМетода, ПараметрыВызова);
КонецЕсли;
Если СтруктураВызоваМетода.Объект <> Параметры.ПроверяемыйОбъект Тогда
ВызватьИсключение "Установлен другой проверяемый объект";
КонецЕсли;
Параметры.СтруктураВызоваМетода = СтруктураВызоваМетода;
Возврат МокитоПроверки;
КонецФункции
// Равно.
// Проверяет подобранные вызовы. Их количество должно быть равно переданному значение, иначе вызывается исключение
// Параметры:
// Количество - Число - Ожидаемое количество вызовов
// Описание - Строка - Описание проверки, необходимо для идентификации упавшей проверки
//
// Возвращаемое значение:
// ОбщийМодуль
Функция Равно(Количество, Знач Описание = Неопределено) Экспорт
Статистика = СтатистикаВызовов();
ЮТУтверждения
.Что(Статистика, Описание)
.ИмеющееПредставление(ОписаниеПроверяемогоОбъекта())
.ИмеетДлину(Количество);
Возврат МокитоПроверки;
КонецФункции
// Больше.
// Проверяет подобранные вызовы. Их количество должно быть больше переданного значения, иначе вызывается исключение
// Параметры:
// Количество - Число
// Описание - Строка - Описание проверки, необходимо для идентификации упавшей проверки
//
// Возвращаемое значение:
// ОбщийМодуль
Функция Больше(Количество, Знач Описание = Неопределено) Экспорт
Статистика = СтатистикаВызовов();
ЮТУтверждения
.Что(Статистика, Описание)
.ИмеющееПредставление(ОписаниеПроверяемогоОбъекта())
.ИмеетДлинуБольше(Количество);
Возврат МокитоПроверки;
КонецФункции
// Меньше.
// Проверяет подобранные вызовы. Их количество должно быть меньше переданного значения, иначе вызывается исключение
// Параметры:
// Количество - Число
// Описание - Строка - Описание проверки, необходимо для идентификации упавшей проверки
//
// Возвращаемое значение:
// ОбщийМодуль
Функция Меньше(Количество, Знач Описание = Неопределено) Экспорт
Статистика = СтатистикаВызовов();
ЮТУтверждения
.Что(Статистика, Описание)
.ИмеющееПредставление(ОписаниеПроверяемогоОбъекта())
.ИмеетДлинуМеньше(Количество);
Возврат МокитоПроверки;
КонецФункции
// Заполнено.
// Проверяет, что есть вызовы метода, соответствующие условию
// Параметры:
// Описание - Строка - Описание проверки, необходимо для идентификации упавшей проверки
//
// Возвращаемое значение:
// ОбщийМодуль
Функция Заполнено(Знач Описание = Неопределено) Экспорт
Статистика = СтатистикаВызовов(Истина);
ЮТУтверждения
.Что(Статистика, Описание)
.ИмеющееПредставление(ОписаниеПроверяемогоОбъекта())
.Заполнено();
Возврат МокитоПроверки;
КонецФункции
// Пусто.
// Проверяет, что нет вызовов метода, соответствующих условию
// Параметры:
// Описание - Строка - Описание проверки, необходимо для идентификации упавшей проверки
//
// Возвращаемое значение:
// ОбщийМодуль
Функция Пусто(Знач Описание = Неопределено) Экспорт
Статистика = СтатистикаВызовов(Истина);
ЮТУтверждения
.Что(Статистика, Описание)
.ИмеющееПредставление(ОписаниеПроверяемогоОбъекта())
.НеЗаполнено();
Возврат МокитоПроверки;
КонецФункции
#КонецОбласти
/////////////////////////////////////////////////////////////////////////////////
// Экспортные процедуры и функции для служебного использования внутри подсистемы
/////////////////////////////////////////////////////////////////////////////////
#Область СлужебныйПрограммныйИнтерфейс
#КонецОбласти
/////////////////////////////////////////////////////////////////////////////////
// Процедуры и функции, составляющие внутреннюю реализацию модуля
/////////////////////////////////////////////////////////////////////////////////
#Область СлужебныеПроцедурыИФункции
#Область Параметры
// Параметры проверки.
//
// Возвращаемое значение:
// Структура:
// * ПроверяемыйОбъект - Произвольный
// * СтруктураВызоваМетода - см. МокитоСлужебный.СтруктураВызоваМетода
Функция ПараметрыПроверки()
Параметры = МокитоСлужебный.Настройки().ПараметрыПроверки;
Возврат Параметры;
КонецФункции
Процедура УстановитьПараметрыПроверки(Объект = Неопределено, СтруктураВызоваМетода = Неопределено)
ПараметрыОбучения = Новый Структура("ПроверяемыйОбъект, СтруктураВызоваМетода", Объект, СтруктураВызоваМетода);
МокитоСлужебный.Настройки().ПараметрыПроверки = ПараметрыОбучения;
КонецПроцедуры
#КонецОбласти
Функция СтатистикаВызовов(Первый = Ложь)
Параметры = ПараметрыПроверки();
СтруктураВызоваМетода = Параметры.СтруктураВызоваМетода;
ВызовыМетода = МокитоСлужебный.СтатистикаВызовов(СтруктураВызоваМетода.Объект, СтруктураВызоваМетода.ИмяМетода);
Если ВызовыМетода = Неопределено Тогда
Возврат Новый Массив();
КонецЕсли;
Если ЗначениеЗаполнено(СтруктураВызоваМетода.Параметры) Тогда
Результат = Новый Массив();
Для Каждого ВызовМетода Из ВызовыМетода Цикл
Если ВызовМетода.Параметры.Количество() < СтруктураВызоваМетода.Параметры.Количество() Тогда
ВызватьИсключение "Сигнатура метода содержит меньше параметров";
КонецЕсли;
КоличествоПараметров = СтруктураВызоваМетода.Параметры.Количество();
Успешно = Истина;
Для Инд = 0 По КоличествоПараметров - 1 Цикл
Параметр = ВызовМетода.Параметры[Инд];
Условие = СтруктураВызоваМетода.Параметры[Инд];
Если МокитоСлужебный.ЭтоМаскаПарамера(Условие) Тогда
Успешно = МокитоСлужебный.ПроверитьПараметр(Параметр, Условие);
Иначе
Успешно = Параметр = Условие;
КонецЕсли;
Если НЕ Успешно Тогда
Прервать;
КонецЕсли;
КонецЦикла;
Если Успешно Тогда
Результат.Добавить(ВызовМетода);
Если Первый Тогда
Прервать;
КонецЕсли;
КонецЕсли;
КонецЦикла;
ВызовыМетода = Результат;
КонецЕсли;
Возврат ВызовыМетода;
КонецФункции
Функция ОписаниеПроверяемогоОбъекта()
СтруктураВызоваМетода = ПараметрыПроверки().СтруктураВызоваМетода;
Объект = СтруктураВызоваМетода.Объект;
ПредставлениеТипа = ЮТОбщий.ПредставлениеТипа(ТипЗнч(Объект));
Возврат СтрШаблон(" - вызовы метода `%1(%2).%3`,", Объект, ПредставлениеТипа, СтруктураВызоваМетода.ИмяМетода);
КонецФункции
#КонецОбласти

View File

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<mdclass:CommonModule xmlns:mdclass="http://g5.1c.ru/v8/dt/metadata/mdclass" uuid="015f5fd3-8e18-4bb8-9c69-63c1569592ac">
<name>МокитоПроверки</name>
<synonym>
<key>ru</key>
<value>Мокито проверки</value>
</synonym>
<clientManagedApplication>true</clientManagedApplication>
<server>true</server>
<clientOrdinaryApplication>true</clientOrdinaryApplication>
</mdclass:CommonModule>

View File

@ -0,0 +1,581 @@
//©///////////////////////////////////////////////////////////////////////////©//
//
// Copyright 2021-2022 BIA-Technologies Limited Liability Company
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
//©///////////////////////////////////////////////////////////////////////////©//
/////////////////////////////////////////////////////////////////////////////////
// Экспортные процедуры и функции для служебного использования внутри подсистемы
/////////////////////////////////////////////////////////////////////////////////
#Область СлужебныйПрограммныйИнтерфейс
Функция Включен() Экспорт
Возврат ЮТКонтекст.ДанныеКонтекста() <> Неопределено;
КонецФункции
Процедура УстановитьРежим(Режим) Экспорт
Контекст = Настройки();
Контекст.Режим = Режим;
ОчиститьСлужебныеПараметры();
КонецПроцедуры
Функция Настройки() Экспорт
Настройки = ЮТКонтекст.ЗначениеКонтекста(КлючНастроек());
Если Настройки = Неопределено Тогда
ВызватьИсключение "Что-то пошло не так, настройки Мокито не инициализированы";
КонецЕсли;
Возврат Настройки;
КонецФункции
#Область СтруктурыДанных
Функция РежимыРаботы() Экспорт
Режимы = Новый Структура();
Режимы.Вставить("Обучение", "Обучение");
Режимы.Вставить("Тестирование", "Тестирование");
Режимы.Вставить("Проверка", "Проверка");
Возврат Новый ФиксированнаяСтруктура(Режимы);
КонецФункции
Функция ТипыДействийРеакций() Экспорт
ТипыРеакций = Новый Структура();
ТипыРеакций.Вставить("ВернутьРезультат", "ВернутьРезультат");
ТипыРеакций.Вставить("ВыброситьИсключение", "ВыброситьИсключение");
ТипыРеакций.Вставить("Пропустить", "Пропустить");
ТипыРеакций.Вставить("ВызватьОсновнойМетод", "ВызватьОсновнойМетод");
Возврат Новый ФиксированнаяСтруктура(ТипыРеакций);
КонецФункции
#КонецОбласти
Функция АнализВызова(Объект, ИмяМетода, ПараметрыМетода, ПрерватьВыполнение) Экспорт
ПрерватьВыполнение = Ложь;
Если НЕ Включен() Тогда
Возврат Неопределено;
КонецЕсли;
Настройки = Настройки();
ПараметрыПерехвата = ДанныеПерехвата(Объект);
Если ПараметрыПерехвата = Неопределено Тогда
Возврат Неопределено;
КонецЕсли;
РежимыРаботы = РежимыРаботы();
СтруктураВызоваМетода = СтруктураВызоваМетода(Объект, ИмяМетода, ПараметрыМетода);
Если Настройки.Режим = РежимыРаботы.Обучение ИЛИ Настройки.Режим = РежимыРаботы.Проверка Тогда
ПрерватьВыполнение = Истина;
Возврат СтруктураВызоваМетода;
ИначеЕсли Настройки.Режим = РежимыРаботы.Тестирование Тогда
ЗарегистрироватьВызовМетода(Настройки, ПараметрыПерехвата, СтруктураВызоваМетода);
Возврат ПерехватитьВызовМетода(ПараметрыПерехвата, СтруктураВызоваМетода, ПрерватьВыполнение);
КонецЕсли;
КонецФункции
// Структура вызова метода.
//
// Параметры:
// Объект - Произвольный - Объект, которому принадлежит метод
// ИмяМетода - Строка - Имя вызванного метода
// ПараметрыМетода - Массив из Произвольный - Набор параметров, с которыми был вызван метод
//
// Возвращаемое значение:
// Структура - Информация о вызове метода:
// * Объект - Произвольный - Объект, которому принадлежит метод
// * ИмяМетода - Строка - Имя вызванного метода
// * Параметры - Массив из Произвольный - Набор параметров, с которыми был вызван метод
// * Контекст - Строка - Контекст вызова метода
Функция СтруктураВызоваМетода(Объект, ИмяМетода, ПараметрыМетода) Экспорт
Если ЭтоСтруктураВызоваМетода(Объект) Тогда
Возврат Объект;
КонецЕсли;
СтруктураВызоваМетода = Новый Структура("Объект, ИмяМетода, Параметры", Объект, ИмяМетода, ПараметрыМетода);
СтруктураВызоваМетода.Вставить("Контекст");
Возврат СтруктураВызоваМетода;
КонецФункции
Функция ЭтоСтруктураВызоваМетода(Объект) Экспорт
Возврат ТипЗнч(Объект) = Тип("Структура");
КонецФункции
#Область Предикаты
Функция ТипыУсловийПараметров() Экспорт
Типы = Новый Структура;
Типы.Вставить("Любой", "Любой");
Типы.Вставить("Значение", "Значение");
Типы.Вставить("Тип", "Тип");
Типы.Вставить("ОписаниеТипа", "ОписаниеТипа");
Возврат Новый ФиксированнаяСтруктура(Типы);
КонецФункции
Функция ОписаниеМаскиПараметра(ТипУсловия, Приоритет) Экспорт
МаскаПараметра = Новый Структура("МаскаСопоставленияПараметров", Истина);
МаскаПараметра.Вставить("Режим", ТипУсловия);
МаскаПараметра.Вставить("Приоритет", Приоритет);
Возврат МаскаПараметра;
КонецФункции
Функция ЭтоМаскаПарамера(Параметр) Экспорт
Возврат ТипЗнч(Параметр) = Тип("Структура") И Параметр.Свойство("МаскаСопоставленияПараметров") И Параметр.МаскаСопоставленияПараметров;
КонецФункции
Функция ПроверитьПараметр(Параметр, Условие) Экспорт
ТипыУсловий = ТипыУсловийПараметров();
Совпадает = Ложь;
Если Условие.Режим = ТипыУсловий.Любой Тогда
Совпадает = Истина;
ИначеЕсли Условие.Режим = ТипыУсловий.Значение Тогда
Совпадает = Условие.Значение = Параметр;
ИначеЕсли Условие.Режим = ТипыУсловий.Тип Тогда
Совпадает = Условие.Тип = ТипЗнч(Параметр);
ИначеЕсли Условие.Режим = ТипыУсловий.ОписаниеТипа Тогда
Совпадает = Условие.Тип.СодержитТип(ТипЗнч(Параметр));
КонецЕсли;
Возврат Совпадает;
КонецФункции
#КонецОбласти
#Область Перехват
Функция ПараметрыПерехвата() Экспорт
Возврат Настройки().Перехват;
КонецФункции
// Данные перехвата.
//
// Параметры:
// Объект - Произвольный
//
// Возвращаемое значение:
// см. МокитоСлужебный.ОписаниеПараметровПерехватаОбъекта
Функция ДанныеПерехвата(Объект) Экспорт
ПараметрыПерехвата = ПараметрыПерехвата();
Если ТипЗнч(Объект) = Тип("Структура") Тогда
Ключ = Объект.Объект;
Иначе
Ключ = Объект;
КонецЕсли;
ПараметрыПерехватаОбъекта = ПараметрыПерехвата[Ключ];
Если ПараметрыПерехватаОбъекта = Неопределено И ЭтоОбъект(Ключ) Тогда
ПараметрыПерехватаОбъекта = ПараметрыПерехвата[Ключ.Ссылка];
КонецЕсли;
Возврат ПараметрыПерехватаОбъекта;
КонецФункции
Процедура ЗарегистрироватьПерехватОбъекта(Знач Объект) Экспорт
Если ЭтоОбъект(Объект) Тогда
Объект = Объект.Ссылка;
КонецЕсли;
ПараметрыПерехвата = ПараметрыПерехвата();
ПараметрыПерехвата.Вставить(Объект, ОписаниеПараметровПерехватаОбъекта(Объект));
КонецПроцедуры
Функция ОписаниеПараметровПерехватаОбъекта(Объект) Экспорт
Возврат Новый Структура("Объект, Методы", Объект, Новый Структура);
КонецФункции
#КонецОбласти
Функция СтатистикаВызовов(Знач Объект, ИмяМетода) Экспорт
Если ЭтоОбъект(Объект) Тогда
Объект = Объект.Ссылка;
КонецЕсли;
Статистика = Настройки().Статистика.Вызовы[Объект];
Если Статистика = Неопределено ИЛИ НЕ Статистика.Свойство(ИмяМетода) Тогда
Возврат Неопределено;
КонецЕсли;
Возврат Статистика[ИмяМетода];
КонецФункции
#Область ОбработчикиСобытий
Процедура ПередТестом(ОписаниеСобытия) Экспорт
ИнициализироватьНастройки();
КонецПроцедуры
Процедура ПослеТеста(ОписаниеСобытия) Экспорт
ОчиститьНастройки();
КонецПроцедуры
#КонецОбласти
Функция МассивПараметров(Параметр1 = "_!%*",
Параметр2 = "_!%*",
Параметр3 = "_!%*",
Параметр4 = "_!%*",
Параметр5 = "_!%*",
Параметр6 = "_!%*",
Параметр7 = "_!%*",
Параметр8 = "_!%*",
Параметр9 = "_!%*",
Параметр10 = "_!%*") Экспорт
ФлагКонец = "_!%*";
Параметры = Новый Массив;
Если Параметр1 <> ФлагКонец Тогда
Параметры.Добавить(Параметр1);
Иначе
Возврат Параметры;
КонецЕсли;
Если Параметр2 <> ФлагКонец Тогда
Параметры.Добавить(Параметр2);
Иначе
Возврат Параметры;
КонецЕсли;
Если Параметр3 <> ФлагКонец Тогда
Параметры.Добавить(Параметр3);
Иначе
Возврат Параметры;
КонецЕсли;
Если Параметр4 <> ФлагКонец Тогда
Параметры.Добавить(Параметр4);
Иначе
Возврат Параметры;
КонецЕсли;
Если Параметр5 <> ФлагКонец Тогда
Параметры.Добавить(Параметр5);
Иначе
Возврат Параметры;
КонецЕсли;
Если Параметр6 <> ФлагКонец Тогда
Параметры.Добавить(Параметр6);
Иначе
Возврат Параметры;
КонецЕсли;
Если Параметр7 <> ФлагКонец Тогда
Параметры.Добавить(Параметр7);
Иначе
Возврат Параметры;
КонецЕсли;
Если Параметр8 <> ФлагКонец Тогда
Параметры.Добавить(Параметр8);
Иначе
Возврат Параметры;
КонецЕсли;
Если Параметр9 <> ФлагКонец Тогда
Параметры.Добавить(Параметр9);
Иначе
Возврат Параметры;
КонецЕсли;
Если Параметр10 <> ФлагКонец Тогда
Параметры.Добавить(Параметр10);
Иначе
Возврат Параметры;
КонецЕсли;
Возврат Параметры;
КонецФункции
#КонецОбласти
/////////////////////////////////////////////////////////////////////////////////
// Процедуры и функции, составляющие внутреннюю реализацию модуля
/////////////////////////////////////////////////////////////////////////////////
#Область СлужебныеПроцедурыИФункции
#Область ОбработкаВызовов
// Зарегистрировать вызов метода.
//
// Параметры:
// Настройки - см. ИнициализироватьНастройки
// ПараметрыПерехвата - см. ДанныеПерехвата
// СтруктураВызоваМетода - см. СтруктураВызоваМетода
Процедура ЗарегистрироватьВызовМетода(Настройки, ПараметрыПерехвата, СтруктураВызоваМетода)
Объект = ПараметрыПерехвата.Объект;
ИмяМетода = СтруктураВызоваМетода.ИмяМетода;
Статистика = Настройки.Статистика.Вызовы[Объект];
Если Статистика = Неопределено Тогда
Статистика = Новый Структура;
Настройки.Статистика.Вызовы.Вставить(Объект, Статистика);
КонецЕсли;
Если НЕ Статистика.Свойство(ИмяМетода) Тогда
Статистика.Вставить(ИмяМетода, Новый Массив);
КонецЕсли;
Статистика[ИмяМетода].Добавить(СтруктураВызоваМетода);
КонецПроцедуры
Функция ПерехватитьВызовМетода(ПараметрыПерехвата, СтруктураВызоваМетода, ПрерватьВыполнение)
Если НЕ ПараметрыПерехвата.Методы.Свойство(СтруктураВызоваМетода.ИмяМетода) Тогда
Возврат Неопределено;
КонецЕсли;
ПараметрыПерехватаМетода = ПараметрыПерехвата.Методы[СтруктураВызоваМетода.ИмяМетода];
Реакция = НайтиРеакцию(ПараметрыПерехватаМетода, СтруктураВызоваМетода);
Если Реакция = Неопределено ИЛИ Реакция.Действие = Неопределено Тогда
Возврат Неопределено;
КонецЕсли;
ПрерватьВыполнение = Истина;
ТипыДействий = ТипыДействийРеакций();
Если Реакция.Действие.ТипДействия = ТипыДействий.ВернутьРезультат Тогда
Реакция.Действие.Обработано = Истина;
Возврат Реакция.Действие.Результат;
ИначеЕсли Реакция.Действие.ТипДействия = ТипыДействий.ВыброситьИсключение Тогда
Реакция.Действие.Обработано = Истина;
ВызватьИсключение Реакция.Действие.Ошибка;
ИначеЕсли Реакция.Действие.ТипДействия = ТипыДействий.Пропустить Тогда
Реакция.Действие.Обработано = Истина;
Возврат Неопределено;
ИначеЕсли Реакция.Действие.ТипДействия = ТипыДействий.ВызватьОсновнойМетод Тогда
Реакция.Действие.Обработано = Истина;
ПрерватьВыполнение = Ложь;
Иначе
ВызватьИсключение "Неизвестный тип действия реакции";
КонецЕсли;
КонецФункции
#КонецОбласти
Функция НайтиРеакцию(ПараметрыПерехватаМетода, СтруктураВызоваМетода)
Реакция = Неопределено;
Приоритет = 0;
ПараметрыВызова = СтруктураВызоваМетода.Параметры;
Для Каждого ВозможнаяРеакция Из ПараметрыПерехватаМетода.Реакции Цикл
ПриоритетВозможнойРеакции = ПроверитьРеакцию(ВозможнаяРеакция, ПараметрыВызова);
Если ПриоритетВозможнойРеакции > Приоритет Тогда
Реакция = ВозможнаяРеакция;
Приоритет = ПриоритетВозможнойРеакции;
КонецЕсли;
КонецЦикла;
Возврат Реакция;
КонецФункции
Функция ПроверитьРеакцию(Реакция, ПараметрыМетода)
Приоритет = 1;
Если Реакция.УсловиеРеакции = Неопределено Тогда
Возврат Приоритет;
КонецЕсли;
Для Инд = 0 По Реакция.УсловиеРеакции.ВГраница() Цикл
Если НЕ ПроверитьПараметр(ПараметрыМетода[Инд], Реакция.УсловиеРеакции[Инд]) Тогда
Возврат 0;
КонецЕсли;
Приоритет = Приоритет + Реакция.УсловиеРеакции[Инд].Приоритет;
КонецЦикла;
Возврат Приоритет;
КонецФункции
#Область Настройки
Процедура ИнициализироватьНастройки() Экспорт
Настройки = Новый Структура;
Настройки.Вставить("Метод");
Настройки.Вставить("Реакция");
Настройки.Вставить("Настройки");
Настройки.Вставить("Перехват", Новый Соответствие);
Настройки.Вставить("Режим", "НеУстановлен");
Настройки.Вставить("Статистика", Новый Структура("Вызовы", Новый Соответствие));
Настройки.Вставить("ПараметрыОбучения", Неопределено);
Настройки.Вставить("ПараметрыПроверки", Неопределено);
ЮТКонтекст.УстановитьЗначениеКонтекста(КлючНастроек(), Настройки);
КонецПроцедуры
Процедура ОчиститьНастройки() Экспорт
ЮТКонтекст.УстановитьЗначениеКонтекста(КлючНастроек(), Неопределено);
КонецПроцедуры
Процедура СброситьПараметры() Экспорт
ИнициализироватьНастройки();
КонецПроцедуры
Функция КлючНастроек()
Возврат "Mockito";
КонецФункции
Процедура ОчиститьСлужебныеПараметры()
Настройки = Настройки();
Настройки.ПараметрыОбучения = Неопределено;
Настройки.ПараметрыПроверки = Неопределено;
КонецПроцедуры
#КонецОбласти
Функция ЭтоСсылка(Значение) Экспорт
Если Значение <> Неопределено Тогда
ТипыСсылок = ОбщегоНазначенияКлиентСервер.ПолучитьОписаниеТиповЛюбаяСсылка();
Результат = ТипыСсылок.СодержитТип(ТипЗнч(Значение));
Иначе
Результат = Ложь;
КонецЕсли;
Возврат Результат;
КонецФункции
Функция ЭтоОбъект(Значение) Экспорт
Если Значение <> Неопределено И ОбщегоНазначенияКлиентСервер.ПеременнаяСодержитСвойство(Значение, "Ссылка") Тогда
Возврат ЭтоСсылка(Значение.Ссылка);
Иначе
Результат = Ложь;
КонецЕсли;
Возврат Результат;
КонецФункции
#КонецОбласти

View File

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<mdclass:CommonModule xmlns:mdclass="http://g5.1c.ru/v8/dt/metadata/mdclass" uuid="f82a31af-cab5-4b81-b1b1-1a16c20d0be8">
<name>МокитоСлужебный</name>
<synonym>
<key>ru</key>
<value>Мокито служебный</value>
</synonym>
<clientManagedApplication>true</clientManagedApplication>
<server>true</server>
<clientOrdinaryApplication>true</clientOrdinaryApplication>
</mdclass:CommonModule>

View File

@ -0,0 +1,182 @@
//©///////////////////////////////////////////////////////////////////////////©//
//
// Copyright 2021-2022 BIA-Technologies Limited Liability Company
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
//©///////////////////////////////////////////////////////////////////////////©//
// @strict-types
/////////////////////////////////////////////////////////////////////////////////
// Экспортные процедуры и функции, предназначенные для использования другими
// объектами конфигурации или другими программами
/////////////////////////////////////////////////////////////////////////////////
#Область ТестыAPI
Процедура ИсполняемыеСценарии() Экспорт
ЮТТесты
.Тест("Обучение")
.Тест("Проверить")
.Тест("МокированиеМетодовСсылочныхОбъектов")
.Тест("НастройкаСерверныхМоковСКлиента")
;
КонецПроцедуры
#КонецОбласти
#Область Тесты
Процедура Обучение() Экспорт
Описание = "Обучение через явный вызов метода";
Мокито.Обучение(РаботаСHTTP)
.Когда(РаботаСHTTP.ОтправитьОбъектНаСервер(Мокито.ЛюбойПараметр(), Мокито.ЛюбойПараметр()))
.Вернуть(1)
.Когда(РаботаСHTTP.ОтправитьОбъектНаСервер(Справочники.ИсточникиДанных.FTP, 2))
.Вернуть(10)
.Прогон();
ЮТУтверждения.Что(РаботаСHTTP.ОтправитьОбъектНаСервер(Справочники.ИсточникиДанных.FTP, 2), Описание + ". Кейс 1")
.Равно(10);
ЮТУтверждения.Что(РаботаСHTTP.ОтправитьОбъектНаСервер(Справочники.ИсточникиДанных.FTP, 1), Описание + ". Кейс 2")
.Равно(1);
Описание = "Обучение через указание имени и набора параметров";
Мокито.Обучение(РаботаСHTTP)
.Когда("ОтправитьОбъектНаСервер", Мокито.МассивПараметров(Мокито.ЛюбойПараметр(), Мокито.ЛюбойПараметр()))
.Вернуть(20)
.Когда("ОтправитьОбъектНаСервер", Мокито.МассивПараметров(Справочники.ИсточникиДанных.FTP, 2))
.Вернуть(2)
.Прогон();
ЮТУтверждения.Что(РаботаСHTTP.ОтправитьОбъектНаСервер(Справочники.ИсточникиДанных.FTP, 2), Описание + ". Кейс 1")
.Равно(2);
ЮТУтверждения.Что(РаботаСHTTP.ОтправитьОбъектНаСервер(Справочники.ИсточникиДанных.FTP, 1), Описание + ". Кейс 2")
.Равно(20);
КонецПроцедуры
Процедура Проверить() Экспорт
ЛюбойПараметр = Мокито.ЛюбойПараметр();
ТипИсточникДанных = Тип("СправочникСсылка.ИсточникиДанных");
Мокито.Обучение(РаботаСHTTP)
.Когда(РаботаСHTTP.ОтправитьОбъектНаСервер(ЛюбойПараметр, ЛюбойПараметр))
.Вернуть(1)
.Когда(РаботаСHTTP.ОтправитьОбъектНаСервер(Справочники.ИсточникиДанных.FTP, 2))
.Вернуть(10)
.Прогон();
РаботаСHTTP.ОтправитьОбъектНаСервер("Справочники.ИсточникиДанных.FTP", Неопределено);
РаботаСHTTP.ОтправитьОбъектНаСервер(Справочники.ИсточникиДанных.FTP, 2);
РаботаСHTTP.ОтправитьОбъектНаСервер(1, 2);
Мокито.Проверить(РаботаСHTTP)
.КоличествоВызовов(РаботаСHTTP.ОтправитьОбъектНаСервер(ЛюбойПараметр, Мокито.ЧисловойПараметр())).Больше(1).Равно(2)
.КоличествоВызовов("ОтправитьОбъектНаСервер").Заполнено().Равно(3).Меньше(6)
.КоличествоВызовов("ОтправитьЗапросHTTP").Пусто().Меньше(1)
.КоличествоВызовов(РаботаСHTTP.ОтправитьОбъектНаСервер(1, 2)).Равно(1)
.КоличествоВызовов(РаботаСHTTP.ОтправитьОбъектНаСервер(ЛюбойПараметр, ЛюбойПараметр)).Равно(3)
.КоличествоВызовов(РаботаСHTTP.ОтправитьОбъектНаСервер(Мокито.ТипизированныйПараметр(ТипИсточникДанных), ЛюбойПараметр)).Равно(1)
;
КонецПроцедуры
Процедура МокированиеМетодовСсылочныхОбъектов() Экспорт
Результат = Новый УникальныйИдентификатор();
// Мокирование обработки проведения (выключение алгоритма проведения)
Документ = ЮТТестовыеДанные.СоздатьДокумент(Документы.ЧекККМ);
Мокито.Обучение(Документ)
.Когда("ОбработкаПроведения").Пропустить()
.Прогон();
Объект = Документ.ПолучитьОбъект();
Объект.ВОжидании = Истина;
Объект.Записать(РежимЗаписиДокумента.Проведение);
Мокито.Проверить(Объект).КоличествоВызовов("ОбработкаПроведения").Заполнено();
Мокито.Проверить(Документ).КоличествоВызовов("ОбработкаПроведения").Заполнено();
Справочник = ЮТТестовыеДанные.СоздатьЭлемент(Справочники.ДополнительныеПараметрыЖурналаДействийПользователя);
СправочникОбъект = Справочник.ПолучитьОбъект();
// Мокирование экспортного метода объекта, указание имени метода
Описание = "Мокирование экспортного метода объекта, указание имени метода";
Мокито.Обучение(Справочник)
.Когда("ПолучитьСтруктуруИзХранилища").Вернуть(Результат)
.Прогон();
ЮТУтверждения.Что(СправочникОбъект.ПолучитьСтруктуруИзХранилища(), Описание)
.Равно(Результат);
Мокито.Проверить(Справочник).КоличествоВызовов("ПолучитьСтруктуруИзХранилища").Заполнено();
// Мокирование экспортного метода объекта, явный вызов метода
Мокито.Сбросить();
Описание = "Мокирование экспортного метода объекта, явный вызов метода";
Мокито.Обучение(СправочникОбъект)
.Когда(СправочникОбъект.ПолучитьСтруктуруИзХранилища()).Вернуть(Результат)
.Прогон();
ЮТУтверждения.Что(Справочник.ПолучитьОбъект().ПолучитьСтруктуруИзХранилища(), Описание)
.Равно(Результат);
Мокито.Проверить(Справочник).КоличествоВызовов("ПолучитьСтруктуруИзХранилища").Заполнено(Описание);
// Мокирование приватного метода
Мокито.Сбросить();
Описание = "Мокирование приватного метода";
Справочник = ЮТТестовыеДанные.СоздатьЭлемент(Справочники.ИсточникиДанных);
СправочникОбъект = Справочник.ПолучитьОбъект();
Пароль = "123";
Пользователь = "админ";
СправочникОбъект.Пользователь = Пользователь;
СправочникОбъект.Пароль = Пароль;
СправочникОбъект.Записать();
ЮТУтверждения.Что(СправочникОбъект, Описание + ". До мокирования")
.Свойство("Пользователь").Равно(Пользователь)
.Свойство("Пароль").НеЗаполнено();
Мокито.Обучение(СправочникОбъект)
.Когда("ПеренестиДанныеВБезопасноеХранилище").Пропустить()
.Прогон();
СправочникОбъект.Пользователь = Пользователь;
СправочникОбъект.Пароль = Пароль;
СправочникОбъект.Записать();
ЮТУтверждения.Что(СправочникОбъект, Описание + ". После мокирования")
.Свойство("Пользователь").Равно(Пользователь)
.Свойство("Пароль").Равно(Пароль);
// Мокирование модуля менеджера
Мокито.Сбросить();
Описание = "Мокирование модуля менеджера";
Мокито.Обучение(Справочники.ИсточникиДанных)
.Когда(Справочники.ИсточникиДанных.СохраненныеБезопасныеДанные(Справочник)).Вернуть(Результат)
.Прогон();
ЮТУтверждения.Что(Справочники.ИсточникиДанных.СохраненныеБезопасныеДанные(Справочник), Описание)
.Равно(Результат);
КонецПроцедуры
#КонецОбласти
#Область СлужебныеПроцедурыИФункции
#КонецОбласти

View File

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<mdclass:CommonModule xmlns:mdclass="http://g5.1c.ru/v8/dt/metadata/mdclass" uuid="9aac5c53-2e22-4eeb-b757-2e1185b66e4b">
<name>ОМ_Мокито</name>
<synonym>
<key>ru</key>
<value>О м мокито</value>
</synonym>
<server>true</server>
</mdclass:CommonModule>

View File

@ -24,33 +24,39 @@
/////////////////////////////////////////////////////////////////////////////////
#Область ТестыAPI
Процедура ИсполняемыеСценарии() Экспорт
Процедура ИсполняемыеСценарии(ДополнительныеПараметры = Неопределено) Экспорт
ЮТТесты
.ТестКлиент("ВыполнитьМодульноеТестирование");
.Тест("ВыброситьИсключение")
;
КонецПроцедуры
#КонецОбласти
#Область Тесты
Процедура ВыполнитьМодульноеТестирование() Экспорт
Процедура ВыброситьИсключение() Экспорт
ПараметрыЗапуска = ЮТФабрика.ПараметрыЗапуска();
ПараметрыЗапуска.CloseAfterTests = Ложь;
ПараметрыЗапуска.filter.extensions = ЮТОбщий.ЗначениеВМассиве("tests");
ПараметрыЗапуска.ВыполнятьМодульноеТестирование = Истина;
ИсточникДанных = ПредопределенноеЗначение("Справочник.ИсточникиДанных.FTP");
ЮТУтверждения.Что(ЮТ, "Не указан каталог отчетов")
.Метод("ВыполнитьМодульноеТестирование").Параметр(ПараметрыЗапуска)
.ВыбрасываетИсключение("Не указан путь сохранения отчета");
ПараметрыЗапуска.reportPath = ЮТТестовыеДанные.НовыйФайл();
ЮТУтверждения.Что(ЮТ, "Указан каталог отчетов")
.Метод("ВыполнитьМодульноеТестирование").Параметр(ПараметрыЗапуска)
.НеВыбрасываетИсключение();
Мокито.Обучение(РаботаСHTTP)
.Когда("ОтправитьОбъектНаСервер")
.ВыброситьИсключение("Не верные параметры вызова")
.Когда(РаботаСHTTP.ОтправитьОбъектНаСервер(ИсточникДанных, Мокито.ЛюбойПараметр()))
.Вернуть(1)
.Прогон();
ЮТУтверждения.Что(РаботаСHTTP)
.Метод("ОтправитьОбъектНаСервер", Мокито.МассивПараметров(ИсточникДанных, 1))
.НеВыбрасываетИсключение()
.Метод("ОтправитьОбъектНаСервер", Мокито.МассивПараметров(1, 1))
.ВыбрасываетИсключение("Не верные параметры вызова");
КонецПроцедуры
#КонецОбласти
#Область СлужебныеПроцедурыИФункции
#КонецОбласти

View File

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<mdclass:CommonModule xmlns:mdclass="http://g5.1c.ru/v8/dt/metadata/mdclass" uuid="f57bbab7-a2c3-4825-8c53-48c1ec6913fb">
<name>ОМ_МокитоОбучение</name>
<synonym>
<key>ru</key>
<value>Мокито обучение</value>
</synonym>
<server>true</server>
</mdclass:CommonModule>

View File

@ -112,7 +112,7 @@
Ошибка = ИнформацияОбОшибке();
КонецПопытки;
ПроверитьОшибкуУтверждения(Ошибка, "Ожидали, что проверяемое значение `Структура` содержит свойство `ЧужоеСвойство`, но это не так");
ПроверитьДанныеОшибкиСравнения(Неопределено, "ЧужоеСвойство");
ПроверитьДанныеОшибкиСравнения(Объект, "ЧужоеСвойство");
Попытка
Ошибка = Неопределено;

View File

@ -0,0 +1,52 @@
//©///////////////////////////////////////////////////////////////////////////©//
//
// Copyright 2021-2022 BIA-Technologies Limited Liability Company
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
//©///////////////////////////////////////////////////////////////////////////©//
&Вместо("ОтправитьОбъектНаСервер")
Функция ЮТОтправитьОбъектНаСервер(ИсточникДанных, Объект, HTTPМетод, ТипКонтента, Преобразование, ДопНастройки, Ответ, ОтветВСтруктуру, ТелоОтветаВХранилище) Экспорт
// Собираем параметры в массив
ПараметрыМетода = Мокито.МассивПараметров(ИсточникДанных, Объект, HTTPМетод, ТипКонтента, Преобразование, ДопНастройки, Ответ, ОтветВСтруктуру, ТелоОтветаВХранилище);
// Отправляем данные на анализ
ПрерватьВыполнение = Ложь;
Результат = Мокито.АнализВызова(РаботаСHTTP, "ОтправитьОбъектНаСервер", ПараметрыМетода, ПрерватьВыполнение);
// Обрабатываем результат анализа
Если НЕ ПрерватьВыполнение Тогда
Возврат ПродолжитьВызов(ИсточникДанных, Объект, HTTPМетод, ТипКонтента, Преобразование, ДопНастройки, Ответ, ОтветВСтруктуру, ТелоОтветаВХранилище);
Иначе
Возврат Результат;
КонецЕсли;
КонецФункции
&Вместо("ОтправитьЗапросHTTP")
Функция ЮТОтправитьЗапросHTTP(ИсточникДанных, HTTPМетод, АдресСкрипта, СтруктураТела, Ответ, СтруктураАвторизации, Параметры, Заголовки, ОтветВСтруктуру, ТелоОтветаВХранилище) Экспорт
ПараметрыМетода = Мокито.МассивПараметров(ИсточникДанных, HTTPМетод, АдресСкрипта, СтруктураТела, Ответ, СтруктураАвторизации, Параметры, Заголовки, ОтветВСтруктуру, ТелоОтветаВХранилище);
ПрерватьВыполнение = Ложь;
Результат = Мокито.АнализВызова(РаботаСHTTP, "ОтправитьЗапросHTTP", ПараметрыМетода, ПрерватьВыполнение);
Если НЕ ПрерватьВыполнение Тогда
Возврат ПродолжитьВызов(ИсточникДанных, HTTPМетод, АдресСкрипта, СтруктураТела, Ответ, СтруктураАвторизации, Параметры, Заголовки, ОтветВСтруктуру, ТелоОтветаВХранилище);
Иначе
Возврат Результат;
КонецЕсли;
КонецФункции

View File

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<mdclass:CommonModule xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:mdclass="http://g5.1c.ru/v8/dt/metadata/mdclass" xmlns:mdclassExtension="http://g5.1c.ru/v8/dt/metadata/mdclass/extension" uuid="7dde6e6e-4f3f-4a05-8429-073cbac79021">
<name>РаботаСHTTP</name>
<objectBelonging>Adopted</objectBelonging>
<extension xsi:type="mdclassExtension:CommonModuleExtension">
<module>Extended</module>
<global>Checked</global>
<clientManagedApplication>Checked</clientManagedApplication>
<server>Checked</server>
<externalConnection>Checked</externalConnection>
<serverCall>Checked</serverCall>
<clientOrdinaryApplication>Checked</clientOrdinaryApplication>
</extension>
<server>true</server>
<clientOrdinaryApplication>true</clientOrdinaryApplication>
<serverCall>true</serverCall>
</mdclass:CommonModule>

View File

@ -49,6 +49,8 @@
// Массив из см. ЮТФабрика.ОписаниеМодуля - Коллекция описаний моделей, структуру элемента см. ЮТФабрика.ОписаниеМодуля
Функция МодулиРасширений() Экспорт
УстановитьПривилегированныйРежим(Истина);
МетаданныеМодулей = Новый Массив;
Для Каждого Модуль Из Метаданные.ОбщиеМодули Цикл

View File

@ -715,6 +715,18 @@
КонецФункции
Функция ПредставлениеТипа(Тип) Экспорт
ТипXML = СериализаторXDTO.XMLТип(Тип);
Если ТипXML = Неопределено Тогда
Возврат "<unknown>";
Иначе
Возврат ТипXML.ИмяТипа;
КонецЕсли;
КонецФункции
#КонецОбласти
/////////////////////////////////////////////////////////////////////////////////

View File

@ -432,14 +432,18 @@
ВставкаСвойство = "";
КонецЕсли;
ПроверяемоеЗначение = Контекст.ПроверяемоеЗначение;
Если ЗначениеЗаполнено(Контекст.ПредставлениеПроверяемогоЗначения) Тогда
ПредставлениеЗначения = Контекст.ПредставлениеПроверяемогоЗначения;
Иначе
ПредставлениеЗначения = СтрШаблон("`%1`", Контекст.ПроверяемоеЗначение);
КонецЕсли;
// Заголовок сообщения
ТекстСообщения = "";
// Тело сообщения
ТекстСообщения = СтрШаблон("ожидали, что %1 `%2`%3 %4, но это не так.",
ТекстСообщения = СтрШаблон("ожидали, что %1 %2%3 %4, но это не так.",
ОбъектПроверки,
ПроверяемоеЗначение,
ПредставлениеЗначения,
ВставкаСвойство,
ТекстОжидания);

View File

@ -137,6 +137,7 @@
ВызватьОбработчикТестовогоМодуля(ИмяСобытия, ОписаниеСобытия);
ВызватьОбработчикРасширения(ИмяСобытия, ОписаниеСобытия);
КонецЕсли;
КонецПроцедуры
#КонецОбласти

View File

@ -38,7 +38,7 @@
Если ЗначениеЗаполнено(Наименование) Тогда
Объект.Наименование = Наименование;
Иначе
ИначеЕсли Объект.Метаданные().ДлинаНаименования > 0 Тогда
Объект.Наименование = Новый УникальныйИдентификатор();
КонецЕсли;
@ -59,7 +59,7 @@
// Реквизиты - Структура, Неопределено - Значения реквизитов элемента
//
// Возвращаемое значение:
// ЛюбаяСсылка - Ссылка на созданный объект
// ДокументСсылка - Ссылка на созданный объект
Функция СоздатьДокумент(Менеджер, Реквизиты = Неопределено) Экспорт
Объект = Менеджер.СоздатьДокумент();

View File

@ -93,6 +93,13 @@
КонецФункции
Функция ИмеющееПредставление(Представление) Экспорт
Контекст().ПредставлениеПроверяемогоЗначения = Представление;
Возврат ЮТУтверждения;
КонецФункции
// Свойство
// Проверяет наличие свойства и запоминает имя свойства для последующей проверки
// Следующая проверка будет относится к этому свойству
@ -590,7 +597,7 @@
// - ТаблицаЗначения
//
// Параметры:
// ОжидаемоеЗначение - Число - Ожидается, что значение Контекста (или его свойство) имеет указанную дину или размер
// ОжидаемоеЗначение - Число - Ожидается, что значение Контекста (или его свойство) имеет указанную длину или размер
// ОписаниеПроверки - Строка - Описание конкретной проверки
//
// Возвращаемое значение:
@ -603,6 +610,72 @@
КонецФункции
// ИмеетДлинуБольше
// Проверяет установленное значение Контекста (или его свойство) на длину или размер коллекции
// Проверка поддерживается для следующих типов проверяемого значения:
// - Строка
// - Массив
// - Структура
// - Соответствие
// - СписокЗначений
// - ФиксированныйМассив
// - ФиксированнаяСтруктура
// - ФиксированноеСоответствие
// - ТаблицаЗначения
//
// Параметры:
// ОжидаемоеЗначение - Число - Ожидается, что значение Контекста (или его свойство) имеет указанную длину или размер
// ОписаниеПроверки - Строка - Описание конкретной проверки
//
// Возвращаемое значение:
// ОбщийМодуль - Этот модуль для замыкания
Функция ИмеетДлинуБольше(Знач ОжидаемоеЗначение, Знач ОписаниеПроверки = Неопределено) Экспорт
УстановитьОписаниеПроверки(ОписаниеПроверки);
ПроверитьТипЗначения(ОжидаемоеЗначение, "Число");
ФактическаяДлина = ДлинаПроверяемогоЗначения();
Результат = ФактическаяДлина > ОжидаемоеЗначение;
Сообщение = СтрШаблон("имеет длину (размер) больше `%1`", ОжидаемоеЗначение);
ОбработатьРезультатСравнения(Результат, Сообщение, Ложь, ФактическаяДлина, ОжидаемоеЗначение);
Возврат ЮТУтверждения;
КонецФункции
// ИмеетДлинуМеньше
// Проверяет установленное значение Контекста (или его свойство) на длину или размер коллекции
// Проверка поддерживается для следующих типов проверяемого значения:
// - Строка
// - Массив
// - Структура
// - Соответствие
// - СписокЗначений
// - ФиксированныйМассив
// - ФиксированнаяСтруктура
// - ФиксированноеСоответствие
// - ТаблицаЗначения
//
// Параметры:
// ОжидаемоеЗначение - Число - Ожидается, что значение Контекста (или его свойство) имеет указанную длину или размер
// ОписаниеПроверки - Строка - Описание конкретной проверки
//
// Возвращаемое значение:
// ОбщийМодуль - Этот модуль для замыкания
Функция ИмеетДлинуМеньше(Знач ОжидаемоеЗначение, Знач ОписаниеПроверки = Неопределено) Экспорт
УстановитьОписаниеПроверки(ОписаниеПроверки);
ПроверитьТипЗначения(ОжидаемоеЗначение, "Число");
ФактическаяДлина = ДлинаПроверяемогоЗначения();
Результат = ФактическаяДлина < ОжидаемоеЗначение;
Сообщение = СтрШаблон("имеет длину (размер) меньше `%1`", ОжидаемоеЗначение);
ОбработатьРезультатСравнения(Результат, Сообщение, Ложь, ФактическаяДлина, ОжидаемоеЗначение);
Возврат ЮТУтверждения;
КонецФункции
// НеИмеетДлину
// Проверяет установленное значение Контекста (или его свойство) на длину или размер коллекции, которые не должны совпадать с указанным значением
// Проверка поддерживается для следующих типов проверяемого значения:
@ -748,6 +821,7 @@
Контекст = Новый Структура;
Контекст.Вставить("ПроверяемоеЗначение", Неопределено);
Контекст.Вставить("ПредставлениеПроверяемогоЗначения", Неопределено);
Контекст.Вставить("ПрефиксОшибки", "");
Контекст.Вставить("ИмяМетода", "");
Контекст.Вставить("ИмяСвойства", "");
@ -1126,9 +1200,7 @@
КонецПроцедуры
Процедура ПроверитьДлину(ОжидаемоеЗначение, Реверс)
ПроверитьТипЗначения(ОжидаемоеЗначение, "Число");
Функция ДлинаПроверяемогоЗначения()
Попытка
ПроверяемоеЗначение = ПроверяемоеЗначение();
@ -1142,11 +1214,16 @@
ЮТРегистрацияОшибок.СгенерироватьОшибкуВыполнения(ТекстОшибки);
КонецЕсли;
Попытка
Результат = ФактическаяДлина = ОжидаемоеЗначение;
Исключение
ЮТРегистрацияОшибок.СгенерироватьОшибкуВыполнения(ИнформацияОбОшибке());
КонецПопытки;
Возврат ФактическаяДлина;
КонецФункции
Процедура ПроверитьДлину(ОжидаемоеЗначение, Реверс)
ПроверитьТипЗначения(ОжидаемоеЗначение, "Число");
ФактическаяДлина = ДлинаПроверяемогоЗначения();
Результат = ФактическаяДлина = ОжидаемоеЗначение;
Сообщение = СтрШаблон("имеет длину (размер) `%1`", ОжидаемоеЗначение);
ОбработатьРезультатСравнения(Результат, Сообщение, Реверс, ФактическаяДлина, ОжидаемоеЗначение);

View File

@ -90,7 +90,7 @@
КонецЕсли;
КонецЕсли;
Данные = ЮТТесты.СценарииМодуля();
Если Ошибка <> Неопределено Тогда

View File

@ -30,11 +30,17 @@
<languageCode>ru</languageCode>
</languages>
<subsystems>Subsystem.ЮТФункциональность</subsystems>
<commonModules>CommonModule.ОМ_ЮТ</commonModules>
<commonModules>CommonModule.Мокито</commonModules>
<commonModules>CommonModule.МокитоОбучение</commonModules>
<commonModules>CommonModule.МокитоПроверки</commonModules>
<commonModules>CommonModule.МокитоСлужебный</commonModules>
<commonModules>CommonModule.ОМ_Мокито</commonModules>
<commonModules>CommonModule.ОМ_МокитоОбучение</commonModules>
<commonModules>CommonModule.ОМ_ЮТИсполнитель</commonModules>
<commonModules>CommonModule.ОМ_ЮТУтверждения</commonModules>
<commonModules>CommonModule.ОМ_ЮТФильтрация</commonModules>
<commonModules>CommonModule.ОМ_ЮТЧитатель</commonModules>
<commonModules>CommonModule.РаботаСHTTP</commonModules>
<commonModules>CommonModule.ЮТ</commonModules>
<commonModules>CommonModule.ЮТИсполнитель</commonModules>
<commonModules>CommonModule.ЮТИсполнительСервер</commonModules>
@ -59,4 +65,7 @@
<commonModules>CommonModule.ЮТФильтрация</commonModules>
<commonModules>CommonModule.ЮТЧитатель</commonModules>
<commonModules>CommonModule.ЮТЧитательСервер</commonModules>
<catalogs>Catalog.ДополнительныеПараметрыЖурналаДействийПользователя</catalogs>
<catalogs>Catalog.ИсточникиДанных</catalogs>
<documents>Document.ЧекККМ</documents>
</mdclass:Configuration>

View File

@ -0,0 +1,31 @@
//©///////////////////////////////////////////////////////////////////////////©//
//
// Copyright 2021-2022 BIA-Technologies Limited Liability Company
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
//©///////////////////////////////////////////////////////////////////////////©//
&Вместо("ОбработкаПроведения")
Процедура ЮТОбработкаПроведения(Отказ, РежимПроведения)
ПараметрыМетода = Мокито.МассивПараметров(Отказ, РежимПроведения);
ПрерватьВыполнение = Ложь;
Мокито.АнализВызова(ЭтотОбъект, "ОбработкаПроведения", ПараметрыМетода, ПрерватьВыполнение);
Если НЕ ПрерватьВыполнение Тогда
ПродолжитьВызов(Отказ, РежимПроведения);
КонецЕсли;
КонецПроцедуры

View File

@ -0,0 +1,15 @@
<?xml version="1.0" encoding="UTF-8"?>
<mdclass:Document xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:mdclass="http://g5.1c.ru/v8/dt/metadata/mdclass" xmlns:mdclassExtension="http://g5.1c.ru/v8/dt/metadata/mdclass/extension" uuid="b842c3f5-c071-4a0f-81c0-9ecf67d6a539">
<producedTypes>
<objectType typeId="98f4435e-201b-4a4b-9d96-423640591111" valueTypeId="eb45180f-f306-4780-95f2-0bf0014ba79d"/>
<refType typeId="576b6b02-25b3-4f3c-a5af-dbaf2d35cd18" valueTypeId="03dce7b3-110f-4647-a4e5-57e8266ae1cd"/>
<selectionType typeId="fa3145f5-4336-4b9c-8f69-bced5388efe3" valueTypeId="bf6dcbf8-d179-49f7-8514-3e922d80744f"/>
<listType typeId="734ce6ac-862f-4614-9f86-44e6080d8f82" valueTypeId="f22f741e-93a3-494f-91cb-2f581d347ce2"/>
<managerType typeId="5aa2be36-c33b-44c4-8176-20e2e6c65a70" valueTypeId="9c358054-f62d-4605-9bf7-13f2a124f4cf"/>
</producedTypes>
<name>ЧекККМ</name>
<objectBelonging>Adopted</objectBelonging>
<extension xsi:type="mdclassExtension:DocumentExtension">
<objectModule>Extended</objectModule>
</extension>
</mdclass:Document>

View File

@ -7,6 +7,7 @@
</synonym>
<includeHelpInContents>true</includeHelpInContents>
<includeInCommandInterface>true</includeInCommandInterface>
<content>CommonModule.МокитоСлужебный</content>
<content>CommonModule.ЮТТестовыеДанные</content>
<content>CommonModule.ЮТУтверждения</content>
<parentSubsystem>Subsystem.ЮТФункциональность</parentSubsystem>

View File

@ -1,3 +1,3 @@
Manifest-Version: 1.0
Runtime-Version: 8.3.10
Base-Project: configuration
Base-Project: BSP

View File

@ -6,9 +6,7 @@
<value>Tests</value>
</synonym>
<objectBelonging>Adopted</objectBelonging>
<extension xsi:type="mdclassExtension:ConfigurationExtension">
<interfaceCompatibilityMode>Checked</interfaceCompatibilityMode>
</extension>
<extension xsi:type="mdclassExtension:ConfigurationExtension"/>
<containedObjects classId="9cd510cd-abfc-11d4-9434-004095e12fc7" objectId="8a9d9b0a-06b5-4386-885a-eb8bcb1b0451"/>
<containedObjects classId="9fcd25a0-4822-11d4-9414-008048da11f9" objectId="43272ea1-9fa7-4bc0-8465-c5f011180e73"/>
<containedObjects classId="e3687481-0a87-462c-a166-9f34594f9bba" objectId="86ef968e-8c32-4c3d-bb3f-7261d74f57ea"/>