{"id":18931786,"url":"https://github.com/nixel2007/moskito","last_synced_at":"2026-02-17T05:34:03.434Z","repository":{"id":54408804,"uuid":"106816591","full_name":"nixel2007/moskito","owner":"nixel2007","description":"Библиотека для создания моков и стабов в стиле mockito","archived":false,"fork":false,"pushed_at":"2021-02-19T21:33:34.000Z","size":145,"stargazers_count":7,"open_issues_count":4,"forks_count":8,"subscribers_count":4,"default_branch":"develop","last_synced_at":"2025-10-10T11:31:56.415Z","etag":null,"topics":["oscript-lib","oscript-package"],"latest_commit_sha":null,"homepage":null,"language":"1C Enterprise","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/nixel2007.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2017-10-13T11:34:50.000Z","updated_at":"2025-05-26T17:45:41.000Z","dependencies_parsed_at":"2022-08-13T14:50:22.342Z","dependency_job_id":null,"html_url":"https://github.com/nixel2007/moskito","commit_stats":null,"previous_names":[],"tags_count":7,"template":false,"template_full_name":null,"purl":"pkg:github/nixel2007/moskito","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nixel2007%2Fmoskito","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nixel2007%2Fmoskito/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nixel2007%2Fmoskito/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nixel2007%2Fmoskito/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/nixel2007","download_url":"https://codeload.github.com/nixel2007/moskito/tar.gz/refs/heads/develop","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nixel2007%2Fmoskito/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29534988,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-17T05:00:25.817Z","status":"ssl_error","status_checked_at":"2026-02-17T04:57:16.126Z","response_time":100,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["oscript-lib","oscript-package"],"created_at":"2024-11-08T11:46:42.600Z","updated_at":"2026-02-17T05:34:03.415Z","avatar_url":"https://github.com/nixel2007.png","language":"1C Enterprise","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Moskito - mock this script!\n\n[![CI](https://github.com/nixel2007/moskito/actions/workflows/main.yml/badge.svg)](https://github.com/nixel2007/moskito/actions/workflows/main.yml)\n[![Статус порога качества](https://sonar.openbsl.ru/api/project_badges/measure?project=moskito\u0026metric=alert_status)](https://sonar.openbsl.ru/dashboard?id=moskito)\n[![Технический долг](https://sonar.openbsl.ru/api/project_badges/measure?project=moskito\u0026metric=sqale_index)](https://sonar.openbsl.ru/dashboard?id=moskito)\n\nБиблиотека предназначена для создания моков (mock) и стабов (stub) в OneScript. За основу взят фреймворк [mockito](http://site.mockito.org/) для Java.\n\n## Цели создания библиотеки\n\nПериодически в тестировании возникают задачи проверки работы модулей или классов, имеющих внешние зависимости. Этими зависимостями могут быть как безобидные вспомогательные классы (например, библиотеки `cmdline`, `logos`), так и зависимости, требующие определенного \"внешнего\" состояния. Например, `Файл` или `HTTPСоединение`.\n\nДля возможности эмуляции работы таких классов и была создана эта библиотека.\n\n## Примеры использования\n\n### Эмуляция работы http-соединения\n\n```bsl\n\nHTTPЗапрос = Новый HTTPЗапрос(\"/ping\");\n\nМокСоединение = Мок.Получить(Новый HTTPСоединение(\"localhost\"));\n\n// Вызов метода Получить по умолчанию вернет NULL, без исключений о недоступности сервиса\nРезультат = МокСоединение.Получить(HTTPЗапрос);\nОжидаем.Что(Результат).Равно(NULL);\n\n// Но можно вызвать исключение\nМокСоединение.Когда().Получить(HTTPЗапрос).ТогдаВыбрасываетИсключение(Новый ИнформацияОбОшибке(\"Ресурс недоступен\", Новый Структура));\nМассивПараметров = Новый Массив;\nМассивПараметров.Добавить(HTTPЗапрос);\nОжидаем.Что(МокСоединение).Метод(\"Получить\", МассивПараметров).ВыбрасываетИсключение(\"Ресурс недоступен\");\n\n// Начальные свойства мокируемого объекта переносятся в сам мок\nОжидаем.Что(МокСоединение.Сервер).Равно(\"localhost\");\n\n// Можно переопределить результат работы метода\nМокСоединение.Когда().Получить(HTTPЗапрос).ТогдаВозвращает(\"Переопределенный ответ\");\nРезультат = МокСоединение.Получить(HTTPЗапрос);\nОжидаем.Что(Результат).Равно(\"Переопределенный ответ\");\n\n// Некоторые объекты нельзя создавать через конструктор.\n// Для таких объектов можно воспользоваться созданием мока из типа.\nОтвет = Мок.Получить(Тип(\"HTTPОтвет\"));\nОтвет.КодСостояния = 200;\nОтвет.Когда().ПолучитьТелоКакСтроку().ТогдаВозвращает(\"Переопределенный ответ\");\n\n// Моки можно вкладывать в моки\nМокСоединение.Когда().Получить(HTTPЗапрос).ТогдаВозвращает(Ответ);\nРезультат = МокСоединение.Получить(HTTPЗапрос);\nОжидаем.Что(Результат.ПолучитьТелоКакСтроку()).Равно(\"Переопределенный ответ\");\n\n// При этом вызов метода с другими параметрами продолжит возвращать NULL\nРезультат = МокСоединение.Получить(\"/test\");\nОжидаем.Что(Результат).Равно(NULL);\n```\n\n### Использование матчеров\n\nДля переопределения результатов методов не обязательно передавать точные значения параметров. Можно использовать \"матчеры\". Матчер - это специальная функция, которая проверяет, что параметр удовлетворяет какому-то условию.\n\n```bsl\n\nМокОбъект = Мок.Получить(Тип(\"Структура\"));\n\n// Заставим структуру для проверки всех свойств возвращать \"Истина\"\nМокОбъект.Когда().Свойство(Матчеры.ЛюбаяСтрока()).ТогдаВозвращает(Истина);\n\n// Теперь любой вызов метода \"Свойства\" с переданной строкой будет возвращать \"Истина\"\nОжидаем.Что(МокОбъект.Свойство(\"Строка\")).Равно(Истина);\nОжидаем.Что(МокОбъект.Свойство(\"ДругаяСтрока\")).Равно(Истина);\n\n// Вызов функции, например, с числом, продолжит возвращать NULL\nОжидаем.Что(МокОбъект.Свойство(\"ДругаяСтрока\")).Равно(NULL);\n\n```\n\nМатчер - это функция, которая должна вернуть `Истина` или `Ложь`. Вы можете написать матчер любой сложности, используся специальный конструктор.\n\n```bsl\n\n// Функция-матчер принимает минимум один параметр\n//  Значение - Произвольный - само проверяемое значение\n// \n// В функции могут содержаться дополнительные параметры. Значения таких параметров должны передаваться\n// в виде массива при создании матчера.\n//\nФункция БольшеТрех(Знач Значение) Экспорт\n    Возврат Значение \u003e 3;\nКонецФункции\n\nМокОбъект = Мок.Получить(Тип(\"Структура\"));\n\nСвойМатчер = Новый Матчер(ЭтотОбъект, \"БольшеТрех\");\nМокОбъект.Когда().Свойство(СвойМатчер).ТогдаВозвращает(Истина);\n\nОжидаем.Что(МокОбъект.Свойство(0)).Равно(NULL);\nОжидаем.Что(МокОбъект.Свойство(3)).Равно(NULL);\nОжидаем.Что(МокОбъект.Свойство(4)).Равно(Истина);\n\n```\n\n### Переопределение с использованием Ответов\n\nВ сложных тестовых случаях методов `ТогдаВозвращает` и `ТогдаВыбрасываетИсключение` может не хватать. Вы можете реализовать более сложную логику ответа с использованием метода `ТогдаОтвечает`\n\n```bsl\n\n// Допустим у нас есть функция, которая просто возвращает строковую информацию\n// о вызванном методе.\n \nФункция ВернутьИнформациюОВызове(Знач ИнформацияОВызове) Экспорт\n\n    // Параметр ИнформацияОВызове хранит данные о самом моке, вызываемом методе,\n    // и массиве параметров, с которым вызвали этот метод.\n\tМокОбъект = ИнформацияОВызове.Мок();\n\tИмяМетода = ИнформацияОВызове.ИмяМетода();\n\tПараметры = ИнформацияОВызове.Параметры();\n\n    // Преобразование массива в строку.\n\tПараметры = ПроцессорыКоллекций.ИзКоллекции(Параметры).ВСтроку(\", \");\n\n    // Произовльное возвращаемое значение\n\tВозврат СтрШаблон(\"Вызван метод \u003c%1\u003e с параметрами \u003c%2\u003e\", ИмяМетода, Параметры);\n \nКонецФункции\n\n// Создадим указатель на функцию, которая должна вызываться при \"ответе\"\nОтвет = Новый Ответ(ЭтотОбъект, \"ВернутьИнформациюОВызове\");\n\nМокОбъект = Мок.Получить(Тип(\"Структура\"));\n// Когда у мока вызывается метод Свойство(), срабатывает вызов функции, заложенной в \"Ответе\" \nМокОбъект.Когда().Свойство(Матчеры.ЛюбаяСтрока(), Матчеры.ЛюбоеЗначение()).ТогдаОтвечает(Ответ);\n\n// Вызовем функцию\nРезультат = МокОбъект.Свойство(\"Поле\");\n\n// В \"Результате\" получим строку, возвращенную функцией ВернутьИнформациюОВызове\nОжидаем.Что(Результат).Равно(\"Вызван метод \u003cСвойство\u003e с параметрами \u003cПоле, \u003e\");\n\n```\n\n### Проверка вызова методов\n\n```bsl\n// Допустим у нас есть класс, принимающий в себя HTTPСоединение, и вызывающий у него метод Получить()\n// Проверим, что метод Получить() действительно вызывался\n\nМойКласс = Новый МойКласс();\nМокСоединение = Мок.Получить(Новый HTTPСоединение(\"localhost\"));\n\nМойКласс.УстановитьКонтекст(МокСоединение);\nМойКласс.ВызватьМетодКоторыйДолженДернутьПолучить(\"/ping\");\n\n// Если метод Получить не вызывался, будет выдано исключение\nМокСоединение.ПроверитьЧтоВызывалсяМетод().Получить(\"/ping\");\n\n```\n\n### Режим \"шпиона\" (spy)\n\n```bsl\n// Создаем нового шпиона над Структурой\nМокСтруктура = Мок.Следить(Новый Структура);\n\n// Шпион вызывает реальные методы объекта\nМокСтруктура.Вставить(\"Ключ1\", 1);\n\n// Методы \"внутреннего\" объекта работают как обычно\nОжидаем.Что(МокСтруктура.Количество()).Равно(1);\n\nМокСтруктура.Вставить(\"Ключ2\", 2);\n\n// Однако, мы можем все еще можем переопределить (stub) результат работы любого метода\nМокСтруктура.Когда().Количество().ТогдаВозвращает(999);\n\n// В этом случае будет возвращаться наше значение.\nОжидаем.Что(МокСтруктура.Количество()).Равно(999);\n\n```\n\n## Имеющиеся ограничения\n\n* В силу ограничений движка на создание методов с именами, совпадающими с именами глобальных методов, не от всех объектов можно создать идентичный мок. Например, если создать мок от `Массив`, то метод `Найти()`, совпадающий по имени с глобальным методом, будет переименован в метод `_Найти()`. `Структура` же замокается без проблем.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnixel2007%2Fmoskito","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnixel2007%2Fmoskito","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnixel2007%2Fmoskito/lists"}