Создание макета сервера с помощью MSW (Mock Service Worker)


Введение

Mock Service Worker или просто MSW — это библиотека имитаторов, которая использует API Service Worker для перехвата реальных запросов.

MSW предоставляет два различных типа макетов:

  • Service Worker Mocks: в идеале для использования в браузере.
  • Моки сервера: для использования в приложениях nodejs.

В этом примере мы будем использовать макет сервера для Nodejs-приложения и настроим макеты apis для тестирования и разработки.

Я буду использовать этот репозиторий в качестве ссылки для всех примеров в этом посте. Так что не стесняйтесь посмотреть, клонировать и провести собственные тесты: https://github.com/brunohgv/msw-test.

Для получения дополнительной информации вы можете ознакомиться с документацией MSW: https://mswjs.io/docs/.

Реализация

Установка MSW

Установка

Чтобы настроить MSW, нам необходимо установить его.

npm install msw
Войти в полноэкранный режим Выйти из полноэкранного режима

Затем нам нужно создать базовую структуру для имитации сервера.

Создание обработчиков

В этом примере я буду использовать https://jsonplaceholder.typicode.com/ api в качестве ссылки.

Для его создания нам просто нужно определить несколько handlers. Обработчики — это инструкции о том, что делать, когда вы находите запрос в коде. Они будут соответствовать запросам в коде и заменять их на те, которые мы определим здесь.

mocks/handlers.md

const { rest } = require('msw') // import msw
const { TODO_SUCCESS, TODO_ERROR } = require('./todoResponses') // import default responses

const handlers = [
    /*
     * How to read the handler:
     * When finding a GET request (because we are using rest.get)
     * to the "https://jsonplaceholder.typicode.com/todos"
     * replace the call by the callback function I'm passing
     */
  rest.get('https://jsonplaceholder.typicode.com/todos', async (req, res, ctx) => {
    return res(ctx.json(TODO_SUCCESS))
  })
]

module.exports = { handlers } // Export handlers
Вход в полноэкранный режим Выйти из полноэкранного режима

После настройки обработчиков мы можем создать имитируемый сервер.

Создание сервера

Для создания сервера нам нужно просто вызвать функцию setupServer из пакета msw/node

mocks/server.js

const { setupServer } = require('msw/node') // import the setupServer from the msw/node package
const { handlers } = require('./handlers') // import the handlers we created

// This configures a request mocking server with the given request handlers.
const server = setupServer(...handlers)

// Export the server
module.exports = {
    server
}
Вход в полноэкранный режим Выйти из полноэкранного режима

После этого у нас все готово для использования нашего макетного сервера в нашем приложении.

Использование макета сервера

В этом приложении я использую его двумя разными способами:

  • В jest setup
  • Для разработки

Использование в установке Jest

Установка jest

Чтобы установить jest, вам нужно просто запустить

npm install jest
Войти в полноэкранный режим Выйти из полноэкранного режима

Создание настройки Jest для тестов

В этой конфигурации мы собираемся настроить Jest для:

  • Инициализировать сервер, который мы создали перед тестами
  • Сбрасывать обработчики после каждого теста, чтобы предотвратить побочные эффекты в других тестах.
  • И в конце мы собираемся закрыть сервер.

jest.setup.js

const { server } = require('./mocks/server.js')
// Establish API mocking before all tests.
beforeAll(() => server.listen())
// Reset any request handlers that we may add during the tests,
// so they don't affect other tests.
afterEach(() => server.resetHandlers())
// Clean up after the tests are finished.
afterAll(() => server.close())
Вход в полноэкранный режим Выход из полноэкранного режима

После определения конфигурации мы просто должны вызвать ее в конфигурации Jest.

Определение конфигурации Jest

Чтобы определить конфигурацию для использования файла setup, нам просто нужно добавить путь к нему в свойство setupFilesAfterEnv.

jest.config.js

module.exports = {
    setupFilesAfterEnv: ['./jest.setup.js']
}
Вход в полноэкранный режим Выход из полноэкранного режима

И затем, когда мы выполним тесты, они будут использовать наш макет сервера вместо оригинальных вызовов.

Вы можете запустить npm run test, чтобы увидеть выполнение тестов и убедиться, что ответ совпадает с макетом.

Использование для разработки

Для имитации внешних запросов мы можем использовать ту же функцию, которую мы использовали в конфигурации jest для запуска сервера имитации.

Таким образом, это просто — добавить server.listen() в файл index.js.

const express = require("express");
const { server: mockServer } = require('../mocks/server') // importing the server and renaming it to mockServer to avoid misunderstandings
const todoServer = require("./todoServer");

mockServer.listen() // This is going to do all the work to mock the resquests

const app = express()

app.get('/todos', todoServer.getTodos)

app.listen(8080, () => {
    console.log(process.env.NODE_ENV)
    console.log('server started')
})
Вход в полноэкранный режим Выход из полноэкранного режима

Но мы хотим добавить для разработки, а не для производства или других окружений, которые у нас могут быть.
Поэтому в данном случае мы используем переменную окружения, чтобы определить, в какой среде мы находимся.

Я устанавливаю ее в файле package.json, но она может быть в файле .env или устанавливаться вручную в терминале.

{
  ...
  "scripts": {
    "test": "jest",
    "start": "SET NODE_ENV=production&& node index.js",
    "dev": "SET NODE_ENV=development&& node index.js"
  },
  ...
}
Войти в полноэкранный режим Выход из полноэкранного режима

PS: Я использую windows, поэтому команда SET NODE_ENV=environment, для linux и mac вы можете просто использовать NODE_ENV=environment.

Для скрипта npm start я устанавливаю переменную NODE_ENV на production.

Для скрипта npm run dev я устанавливаю переменную NODE_ENV на development.

Эта переменная будет доступна через атрибут process.env.NODE_ENV.

Итак, теперь мы можем определить, будем ли мы использовать макет в зависимости от окружения, просто обернув mockServer.listen() в выражение if.

const express = require("express");
const { server: mockServer } = require('../mocks/server') // importing the server and renaming it to mockServer to avoid misunderstandings
const todoServer = require("./todoServer");

// Just use the mocks if the NODE_ENV is set to 'development'
if(process.env.NODE_ENV === 'development') { 
    mockServer.listen()
}

const app = express()

app.get('/todos', todoServer.getTodos)

app.listen(8080, () => {
    console.log(process.env.NODE_ENV)
    console.log('server started')
})
Вход в полноэкранный режим Выйти из полноэкранного режима

И это все.

Запустив npm start, вы вызовете службу и получите реальный ответ.

Выполнив команду npm run dev, вы замените реальный вызов на имитированный.

Оцените статью
devanswers.ru
Добавить комментарий