Очень мощный, но необычный способ издеваться над сервисом в модульном тесте шутки.

В Jest есть два способа имитировать функции: либо создать фиктивную функцию для использования в тестовом коде, либо написать manual mock для переопределения зависимости модуля. Сегодня я собираюсь продемонстрировать, как использовать ручной макет.

Также это продолжение статьи https://medium.com/@krisma/how-to-implement-queues-in-node-js-8b3a06ce0dd0

Структура решения:

├── gui
│   └── arena.js
├── queues
│   ├── __mocks__
│   │   └── queues.js
│   ├── uploadFileByIdQueue.js
│   └── process.js
├── routes.js
└── tasks
    └── image
        ├── process.js
        ├── queue.js
        └── queue.test.js

Ручные макеты определяются записью модуля в подкаталог __mocks__/ (обычно он размещается непосредственно рядом с модулем, но это не обязательно). Например, чтобы имитировать модуль с именем uploadFileByIdQueue в каталоге queues, создайте файл с именем queues.js и поместите его в каталог queues/__mocks__. Обратите внимание, что папка __mocks__ чувствительна к регистру, поэтому имя папки __MOCKS__ не работает в некоторых системах.

Сценарий:

uploadFileByIdQueue — это внешний триггер для запуска производителя. поэтому мы хотим проверить после его вызова, действительно ли производитель создает задание, которое использует нужные нам параметры. Это может быть намного сложнее, например, некоторые вычисления значений параметров или вызов других API. Здесь мы пропускаем все и просто сравниваем входные данные.

Создайте код для имитации методов модуля

Это относительно просто, так как нас интересует только ввод, поэтому мы просто используем jest.fn(), чтобы вернуть Promise для имитации метода add.

кстати, это равносильно следующему, но с гораздо более открытым интерфейсом

Скажите jest использовать приведенный выше код, чтобы издеваться над нужным нам модулем.

Типичный синтаксис ручной имитации шутки:

jest.mock(moduleName, factory, options),

jest будет имитировать имя модуля с именем, указанным в 1-м параметре, с фабрикой, указанной во 2-м параметре.

Чтобы быть более конкретным, второй аргумент factory можно использовать для указания явной фабрики модулей, которая является обязательной для ручной имитации, потому что мы хотим указать, какой модуль/фиктивный код мы хотим использовать, а не использовать автоматический макет. Например, в первой строке говорится, что jest издевается над «../../queues/queues» с помощью «../../queues/__mocks__/queues», и в результате это больше не авто-моки, jest чтобы использовать код, назначенный во втором параметре, для завершения макета.

const queueMock = require("../../queues/uploadFileByIdQueue").uploadFileByIdQueue;

Эта строка означает, что константа с именем queueMock создается на основе соглашения строки 1 (где найти фиктивный код) для имитации uploadFileByIdQueue. и поэтому, собственно, куда девать __mocks__ не важно.

Запустить тест

Подведение итогов

Мы видим, что ручное макетирование несложно реализовать, однако оно обеспечивает гораздо более гибкий способ имитации, намного более мощный, чем автоматический макет. В частности, в сценарии, таком как доступ к удаленному ресурсу, такому как веб-сайт, база данных или другой экземпляр/служба (в нашем случае доступ к очереди заданий при тестировании контроллера приложения), вы можете создать ручной макет, который позволит вам использовать поддельный данные, но не нарушать зависимость модуля. Это гарантирует, что ваши тесты будут быстрыми и ненадежными.

Для получения более подробной информации, пожалуйста, обратитесь к https://jestjs.io/docs/en/manual-mocks.