Обработчики (handlers) для GET, POST, PUT, DELETE

При тестировании компонентов React, которые взаимодействуют с API, критически важно эмулировать сетевые запросы. Это позволяет проверять поведение приложения без необходимости реального сервера. Для этого применяются обработчики (handlers), которые перехватывают запросы типа GET, POST, PUT и DELETE и возвращают заранее определённые ответы.

Настройка тестовой среды

Наиболее популярным инструментом для перехвата запросов является библиотека MSW (Mock Service Worker). Она позволяет создавать обработчики на уровне сетевых запросов, которые работают как в браузере, так и в Node.js при тестировании.

Базовая структура handler-а:

import { rest } from 'msw';

export const handlers = [
  rest.get('/api/items', (req, res, ctx) => {
    return res(
      ctx.status(200),
      ctx.json([{ id: 1, name: 'Item 1' }])
    );
  }),
];
  • rest.get указывает, что перехватывается GET-запрос.
  • Параметры функции: req (запрос), res (формирование ответа), ctx (контекст ответа).
  • ctx.status задаёт HTTP-статус, ctx.json возвращает JSON-данные.

Обработчик GET-запросов

GET-запросы обычно используются для получения данных. Тестирование компонентов с GET-запросами включает проверку:

  • правильного отображения данных из ответа,
  • обработки состояния загрузки,
  • корректной реакции на ошибки (например, 404 или 500).

Пример обработчика GET с симуляцией задержки:

rest.get('/api/users', (req, res, ctx) => {
  return res(
    ctx.delay(150), // имитация сетевой задержки
    ctx.status(200),
    ctx.json([{ id: 1, username: 'admin' }])
  );
});

Обработчик POST-запросов

POST-запросы применяются для создания новых ресурсов. При тестировании важно проверять:

  • корректную отправку данных на сервер,
  • обработку ответа с новым объектом,
  • реакции на ошибки (например, дубликаты или недопустимые значения).

Пример POST-handler-а:

rest.post('/api/items', (req, res, ctx) => {
  const { name } = req.body;
  if (!name) {
    return res(
      ctx.status(400),
      ctx.json({ error: 'Name is required' })
    );
  }
  return res(
    ctx.status(201),
    ctx.json({ id: Math.floor(Math.random() * 1000), name })
  );
});
  • req.body содержит данные, отправленные компонентом.
  • Можно реализовать проверку обязательных полей и возвращать ошибки.

Обработчик PUT-запросов

PUT-запросы используются для обновления существующих ресурсов. Тесты проверяют:

  • правильность изменения данных,
  • обработку отсутствующих ресурсов,
  • реакции на ошибки сервера.

Пример PUT-handler-а:

rest.put('/api/items/:id', (req, res, ctx) => {
  const { id } = req.params;
  const { name } = req.body;
  if (!name) {
    return res(
      ctx.status(400),
      ctx.json({ error: 'Name is required' })
    );
  }
  return res(
    ctx.status(200),
    ctx.json({ id, name })
  );
});
  • Использование :id в пути позволяет динамически перехватывать запросы к разным ресурсам.

Обработчик DELETE-запросов

DELETE-запросы применяются для удаления ресурсов. Тестирование включает:

  • подтверждение удаления в UI,
  • проверку обработки несуществующих ресурсов,
  • реакции на серверные ошибки.

Пример DELETE-handler-а:

rest.delete('/api/items/:id', (req, res, ctx) => {
  const { id } = req.params;
  if (id !== '1') {
    return res(
      ctx.status(404),
      ctx.json({ error: 'Item not found' })
    );
  }
  return res(
    ctx.status(204) // No Content
  );
});
  • Код 204 используется для успешного удаления без тела ответа.

Объединение обработчиков

Все обработчики обычно объединяются в массив и подключаются к setupServer из MSW:

import { setupServer } from 'msw/node';
import { handlers } from './handlers';

const server = setupServer(...handlers);

beforeAll(() => server.listen());
afterEach(() => server.resetHandlers());
afterAll(() => server.close());
  • server.listen() запускает перехват запросов.
  • server.resetHandlers() очищает изменения между тестами.
  • server.close() завершает работу после всех тестов.

Динамическое изменение поведения в тестах

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

server.use(
  rest.get('/api/users', (req, res, ctx) => {
    return res(ctx.status(500), ctx.json({ error: 'Server error' }));
  })
);

Это полезно для проверки поведения компонентов при ошибках сети или сервера.

Преимущества использования handlers

  • Полная изоляция тестов от реального API.
  • Возможность моделировать любые сценарии: успех, ошибки, задержки.
  • Простое управление различными методами запросов (GET, POST, PUT, DELETE) с минимальным дублированием кода.
  • Удобство интеграции с Jest, Testing Library и другими инструментами тестирования React.

Эффективное использование обработчиков позволяет создавать надёжные, повторяемые тесты компонентов, которые взаимодействуют с сервером, без зависимости от внешних сервисов.