Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Добавлен мок объекта HTTPОтвет #478

Open
wants to merge 2 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions documentation/docs/features/mocking/mocking.md
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,27 @@ sequenceDiagram
* `БазовыйURL()`
* `ОтносительныйURL()`

### `HTTPОтвет`
При тестировании HTTP-запросов возникает необходимость использовать мок для эмуляции объекта `HTTPОтвет`.

Для таких кейсов был добавлен [`ЮТест.Данные().HTTPОтвет`](/api/ЮТТестовыеДанные#httpответ) реализующий интерфейс `HTTPОтвет`.

* Свойства
* `Заголовки` \ `Headers`
* `КодСостояния` \ `StatusCode`
* Методы
* `ПолучитьИмяФайлаТела()` \ `GetBodyFileName()`
* `ПолучитьТелоКакДвоичныеДанные()` \ `GetBodyAsBinaryData()`
* `ПолучитьТелоКакПоток()` \ `GetBodyAsStream()`
* `ПолучитьТелоКакСтроку()` \ `GetBodyAsString()`
* Методы настройки, реализованные в виде [текучих выражений](/docs/getting-started/fluent-api.md)
* `ЗаписатьТелоВФайл()` - Записывает тело в файл, устанавливает тело и имя файла для чтения тела
* `ДобавитьЗаголовки()` - Добавляет заголовки
* `ДобавитьЗаголовок()` - Добавляет заголовок
* `УстановитьИмяФайлаТела()` - Устанавливает имя файла для чтения тела
* `УстановитьКодСостояния()` - Устанавливает код состояния
* `УстановитьТело()` - Устанавливает тело из строки или двоичных данных

### `ADO.RecordSet`

При тестировании прямых запросов к СУБД также возникает потребность использовать мок, для эмуляции чтения из `ADO.RecordSet`.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1010,6 +1010,16 @@
Возврат Обработки.ЮТHTTPСервисЗапрос.Создать();
КонецЕсли;

КонецФункции

// Возвращает мок для `HTTPОтвет`.
//
// Возвращаемое значение:
// ОбработкаОбъект.ЮТHTTPОтвет - Мок
Функция HTTPОтвет() Экспорт

Возврат Обработки.ЮТHTTPОтвет.Создать();

КонецФункции
#КонецЕсли

Expand Down
1 change: 1 addition & 0 deletions exts/yaxunit/src/Configuration/Configuration.mdo
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,7 @@
<commonModules>CommonModule.ЮТЧитательСлужебный</commonModules>
<commonModules>CommonModule.ЮТЧитательСлужебныйВызовСервера</commonModules>
<dataProcessors>DataProcessor.ЮТHTTPServiceRequest</dataProcessors>
<dataProcessors>DataProcessor.ЮТHTTPОтвет</dataProcessors>
<dataProcessors>DataProcessor.ЮТHTTPСервисЗапрос</dataProcessors>
<dataProcessors>DataProcessor.ЮТRecordSet</dataProcessors>
<dataProcessors>DataProcessor.ЮТКонструкторДвижений</dataProcessors>
Expand Down
335 changes: 335 additions & 0 deletions exts/yaxunit/src/DataProcessors/ЮТHTTPОтвет/ObjectModule.bsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,335 @@
//©///////////////////////////////////////////////////////////////////////////©//
//
// Copyright 2021-2025 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.
//
//©///////////////////////////////////////////////////////////////////////////©//

#Если Сервер Тогда

#Область ОписаниеПеременных

// Заголовки
Перем Headers Экспорт; // ENG
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔗Не рекомендуется использовать экспортные переменные. Это может стать источником трудновоспроизводимых ошибок

CODE_SMELL Codesmell  MAJOR Major

standard unpredictable design  Why is this an issue?

Перем Заголовки Экспорт;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔗Не рекомендуется использовать экспортные переменные. Это может стать источником трудновоспроизводимых ошибок

CODE_SMELL Codesmell  MAJOR Major

standard unpredictable design  Why is this an issue?


// Код состояния
Перем StatusCode Экспорт; // ENG
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔗Не рекомендуется использовать экспортные переменные. Это может стать источником трудновоспроизводимых ошибок

CODE_SMELL Codesmell  MAJOR Major

standard unpredictable design  Why is this an issue?

Перем КодСостояния Экспорт;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔗Не рекомендуется использовать экспортные переменные. Это может стать источником трудновоспроизводимых ошибок

CODE_SMELL Codesmell  MAJOR Major

standard unpredictable design  Why is this an issue?


// Контекст конструктора
Перем Контекст;

#КонецОбласти

#Область ПрограммныйИнтерфейс

#Область HTTPОтвет

// Получает имя файла, в который было записано тело (ENG)
//
// Возвращаемое значение:
// - Строка - Имя файла
// - Неопределено - Если тело не записывалось в файл
//
Функция GetBodyFileName() Экспорт

Возврат ПолучитьИмяФайлаТела();

КонецФункции

// Получает тело в виде двоичных данных (ENG)
//
// Возвращаемое значение:
// - ДвоичныеДанные - Тело в виде двоичных данных
// - Неопределено - Если тело записывалось в файл
//
Функция GetBodyAsBinaryData() Экспорт

Возврат ПолучитьТелоКакДвоичныеДанные();

КонецФункции

// Получает поток для чтения тела (ENG)
//
// Возвращаемое значение:
// - Поток - Если тело не записывалось в файл
// - ФайловыйПоток - Если тело записывалось в файл
//
Функция GetBodyAsStream() Экспорт

Возврат ПолучитьТелоКакПоток();

КонецФункции

// Получает тело в виде строки (ENG)
//
// Параметры:
// Кодировка - КодировкаТекста, Строка - Указывает кодировку, в которой должно интерпретироваться тело
//
// Возвращаемое значение:
// - Строка - Тело в виде строки
// - Неопределено - Если тело записывалось в файл
//
Функция GetBodyAsString(Кодировка = Неопределено) Экспорт

Возврат ПолучитьТелоКакСтроку(Кодировка);

КонецФункции

// Получает имя файла, в который было записано тело
//
// Возвращаемое значение:
// - Строка - Имя файла
// - Неопределено - Если тело не записывалось в файл
//
Функция ПолучитьИмяФайлаТела() Экспорт

Если НЕ Контекст.ИзФайла Тогда
Возврат Неопределено;
КонецЕсли;

Возврат Контекст.ИмяФайла;

КонецФункции

// Получает тело в виде двоичных данных
//
// Возвращаемое значение:
// - ДвоичныеДанные - Тело в виде двоичных данных
// - Неопределено - Если тело записывалось в файл
//
Функция ПолучитьТелоКакДвоичныеДанные() Экспорт

Если Контекст.ИзФайла Тогда
Возврат Неопределено;
КонецЕсли;

ТипТела = ТипЗнч(Контекст.Тело);

Если ТипТела = Тип("ДвоичныеДанные") Тогда
ДвоичныеДанные = Контекст.Тело;
ИначеЕсли ТипТела = Тип("Строка") Тогда
ДвоичныеДанные = ПолучитьДвоичныеДанныеИзСтроки(Контекст.Тело);
Иначе
ДвоичныеДанные = ПолучитьДвоичныеДанныеИзСтроки("");
КонецЕсли;

Возврат ДвоичныеДанные;

КонецФункции

// Получает поток для чтения тела
//
// Возвращаемое значение:
// - Поток - Если тело не записывалось в файл
// - ФайловыйПоток - Если тело записывалось в файл
//
Функция ПолучитьТелоКакПоток() Экспорт

Если Контекст.ИзФайла Тогда
Поток = Новый ФайловыйПоток(Контекст.ИмяФайла, РежимОткрытияФайла.Открыть);
Иначе
Поток = ПолучитьТелоКакДвоичныеДанные().ОткрытьПотокДляЧтения();
КонецЕсли;

Возврат Поток;

КонецФункции

// Получает тело в виде строки
//
// Параметры:
// Кодировка - КодировкаТекста, Строка - Указывает кодировку, в которой должно интерпретироваться тело
//
// Возвращаемое значение:
// - Строка - Тело в виде строки
// - Неопределено - Если тело записывалось в файл
//
Функция ПолучитьТелоКакСтроку(Кодировка = Неопределено) Экспорт

Если Контекст.ИзФайла Тогда
Возврат Неопределено;
КонецЕсли;

ТипТела = ТипЗнч(Контекст.Тело);

Если ТипТела = Тип("ДвоичныеДанные") Тогда
Тело = ПолучитьСтрокуИзДвоичныхДанных(Контекст.Тело, Кодировка);
ИначеЕсли ТипТела = Тип("Строка") Тогда
Тело = Контекст.Тело;
Иначе
Тело = "";
КонецЕсли;

Возврат Тело;

КонецФункции

#КонецОбласти

#Область Конструктор

// Записывает тело в файл, устанавливает тело и имя файла для чтения тела
//
// Параметры:
// Тело - Строка - Тело в виде строки
// - ДвоичныеДанные - Тело в виде двоичных данных
// - Неопределено - Будет взято тело установленное через метод УстановитьТело
// ИмяФайла - Строка - Имя файла
// - Неопределено - Будет взято имя установленное через метод УстановитьИмяФайлаТела
// или сгенерировано имя временного файла
//
// Возвращаемое значение:
// ОбработкаОбъект.ЮТHTTPОтвет - Конструктор
//
Функция ЗаписатьТелоВФайл(Тело = Неопределено, ИмяФайла = Неопределено) Экспорт

Если Тело = Неопределено И ЗначениеЗаполнено(Контекст.Тело) Тогда
Тело = Контекст.Тело;
КонецЕсли;

Если ИмяФайла = Неопределено Тогда
Если ЗначениеЗаполнено(Контекст.ИмяФайла) Тогда
ИмяФайла = Контекст.ИмяФайла;
Иначе
ИмяФайла = ПолучитьИмяВременногоФайла();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔗Нужно добавить удаление временного файла после использования

BUG Bug  MAJOR Major

standard badpractice parameters  Why is this an issue?

КонецЕсли;
КонецЕсли;

УстановитьТело(Тело);
УстановитьИмяФайлаТела(ИмяФайла);
ДвоичныеДанные = ПолучитьТелоКакДвоичныеДанные();
ДвоичныеДанные.Записать(ИмяФайла);
Возврат ЭтотОбъект;

КонецФункции

// Добавляет заголовки
//
// Параметры:
// Значения - Соответствие:
// * Ключ - Строка - Наименование заголовка
// * Значение - Строка - Значение заголовка
//
// Возвращаемое значение:
// ОбработкаОбъект.ЮТHTTPОтвет - Конструктор
//
Функция ДобавитьЗаголовки(Значения) Экспорт

Для Каждого ЭлементКоллекции Из Значения Цикл
ДобавитьЗаголовок(ЭлементКоллекции.Ключ, ЭлементКоллекции.Значение);
КонецЦикла;

Возврат ЭтотОбъект;

КонецФункции

// Добавляет заголовок
//
// Параметры:
// Ключ - Строка - Наименование заголовка
// Значение - Строка - Значение заголовка
//
// Возвращаемое значение:
// ОбработкаОбъект.ЮТHTTPОтвет - Конструктор
//
Функция ДобавитьЗаголовок(Ключ, Значение) Экспорт

Headers.Вставить(Ключ, Значение);
Заголовки.Вставить(Ключ, Значение);
Возврат ЭтотОбъект;

КонецФункции

// Устанавливает имя файла для чтения тела
//
// Параметры:
// ИмяФайла - Строка - Имя файла
//
// Возвращаемое значение:
// ОбработкаОбъект.ЮТHTTPОтвет - Конструктор
//
Функция УстановитьИмяФайлаТела(ИмяФайла) Экспорт

Контекст.ИзФайла = Истина;
Контекст.ИмяФайла = ИмяФайла;
Возврат ЭтотОбъект;

КонецФункции

// Устанавливает код состояния
//
// Параметры:
// Значение - Число - Код состояния
//
// Возвращаемое значение:
// ОбработкаОбъект.ЮТHTTPОтвет - Конструктор
//
Функция УстановитьКодСостояния(Значение) Экспорт

StatusCode = Значение;
КодСостояния = Значение;
Возврат ЭтотОбъект;

КонецФункции

// Устанавливает тело
//
// Параметры:
// Тело - Строка - Тело в виде строки
// - ДвоичныеДанные - Тело в виде двоичных данных
//
// Возвращаемое значение:
// ОбработкаОбъект.ЮТHTTPОтвет - Конструктор
//
Функция УстановитьТело(Тело) Экспорт

Контекст.Тело = Тело;
Возврат ЭтотОбъект;

КонецФункции

#КонецОбласти

#КонецОбласти

#Область СлужебныеПроцедурыИФункции

// Инициализирует начальные значения переменных
//
Процедура Инициализировать()

Заголовки = Новый Соответствие();
Headers = Новый Соответствие();

КодСостояния = 0;
StatusCode = 0;

Контекст = Новый Структура;
Контекст.Вставить("ИзФайла", Ложь);
Контекст.Вставить("ИмяФайла", "");
Контекст.Вставить("Тело", Неопределено);

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

#КонецОбласти

#Область Инициализация

Инициализировать();

#КонецОбласти

#КонецЕсли
Loading
Loading