MSW (Mock Service Worker) — инструмент для перехвата сетевых запросов на уровне сервис-воркера или node-среды. В контексте тестирования с Jest MSW позволяет полностью контролировать ответы API, изолировать тесты от внешних сервисов и повысить стабильность тестов. Ниже описан подробный процесс интеграции MSW в среду Jest.
Для работы с MSW в node-среде необходимо установить два основных пакета:
npm install msw --save-dev
npm install @testing-library/react @testing-library/jest-dom --save-dev
msw — основной пакет для создания обработчиков
запросов.@testing-library/react и
@testing-library/jest-dom — вспомогательные библиотеки для
тестирования React-компонентов.Для запуска тестов в среде Node (Jest) используется node-request-interception, встроенная возможность MSW. Настройка браузерного сервис-воркера не требуется.
Обработчики определяют, какие запросы перехватывать и какие ответы возвращать. Структура обработчика проста:
import { rest } from 'msw';
export const handlers = [
rest.get('/api/users', (req, res, ctx) => {
return res(
ctx.status(200),
ctx.json([
{ id: 1, name: 'Alice' },
{ id: 2, name: 'Bob' }
])
);
}),
rest.post('/api/login', (req, res, ctx) => {
const { username } = req.body;
return res(
ctx.status(200),
ctx.json({ token: `token-for-${username}` })
);
})
];
rest.get, rest.post и другие методы
определяют HTTP-метод запроса.req содержит параметры запроса, заголовки и тело.res создаёт ответ, а ctx предоставляет
вспомогательные методы для формирования статуса, заголовков и тела.Важно использовать чистые, предсказуемые ответы, чтобы тесты оставались детерминированными.
Для node-среды создаётся отдельный сервер:
import { setupServer } from 'msw/node';
import { handlers } from './handlers';
export const server = setupServer(...handlers);
setupServer принимает список обработчиков и создаёт
сервер, который будет управлять всеми перехваченными запросами во время
тестов.
Чтобы сервер корректно работал с Jest, необходимо использовать хуки
beforeAll, afterEach и
afterAll:
// jest.setup.js
import { server } from './server';
import '@testing-library/jest-dom/extend-expect';
beforeAll(() => server.listen());
afterEach(() => server.resetHandlers());
afterAll(() => server.close());
server.listen() — запускает перехват запросов перед
тестами.server.resetHandlers() — сбрасывает любые временные
обработчики, добавленные внутри отдельных тестов.server.close() — завершает работу сервера после всех
тестов, освобождая ресурсы.Важно подключить этот файл в конфигурации Jest:
"setupFilesAfterEnv": ["<rootDir>/jest.setup.js"]
MSW позволяет временно изменять поведение API для отдельного теста:
import { server } from './server';
import { rest } from 'msw';
test('обрабатывает ошибку сервера', async () => {
server.use(
rest.get('/api/users', (req, res, ctx) => {
return res(ctx.status(500));
})
);
// логика теста, проверка обработки ошибки
});
server.use() добавляет новые обработчики только для
текущего теста.server.resetHandlers().При тестировании компонентов React с асинхронными запросами важно использовать функции RTL:
findBy* для ожидания элементов после завершения
запроса.waitFor для контроля состояния компонента.Пример теста с MSW и React Testing Library:
import { render, screen } from '@testing-library/react';
import UsersList from './UsersList';
test('отображает список пользователей', async () => {
render(<UsersList />);
const alice = await screen.findByText('Alice');
const bob = await screen.findByText('Bob');
expect(alice).toBeInTheDocument();
expect(bob).toBeInTheDocument();
});
В этом примере MSW перехватывает запрос к /api/users и
возвращает заранее определённый список, что делает тест полностью
независимым от реального API.
ctx.delay() для симуляции сетевой
задержки.ctx.log()
для отладки сложных сценариев.Эта настройка создаёт надёжное и предсказуемое окружение для тестирования React-приложений, позволяя полностью контролировать сетевое взаимодействие внутри Jest.