Увійти Реєстрація
Блог Серії
Кар'єра
Вакансії Компанії
Навчання
Документація Співбесіди Тестування Відео
Екосистема
Пакети Ресурси Проєкти Інструменти Події
Інше
Про нас Реклама

Як підміняти запити до API в тестах React через MSW?

Тести компонентів, що завантажують дані, не повинні ходити в справжній API: повільно, нестабільно, залежить від стану бази. Підмінити fetch через vi.mock можна, але тоді тест прив'язаний до того, як код робить запит.

MSW (Mock Service Worker) перехоплює запити на рівні мережі: компонент викликає звичайний fetch чи axios, а відповідь надходить з обробника тесту.

// src/test/handlers.ts
import { http, HttpResponse } from 'msw';

export const handlers = [
  http.get('/api/vacancies', () =>
    HttpResponse.json([{ id: 1, title: 'Laravel-розробник' }]),
  ),
  http.post('/api/vacancies/:id/apply', async ({ params, request }) => {
    const body = await request.json();
    return HttpResponse.json({ id: params.id, email: body.email }, { status: 201 });
  }),
];
// src/test/setup.ts
import { setupServer } from 'msw/node';
import { handlers } from './handlers';

export const server = setupServer(...handlers);

beforeAll(() => server.listen({ onUnhandledRequest: 'error' }));
afterEach(() => server.resetHandlers());
afterAll(() => server.close());

Інший сценарій в окремому тесті - перевизначити обробник:

test('показує помилку сервера', async () => {
  server.use(http.get('/api/vacancies', () => new HttpResponse(null, { status: 500 })));

  render(<VacancyList />);
  expect(await screen.findByRole('alert')).toHaveTextContent('Не вдалося завантажити');
});

resetHandlers() після тесту повертає типові обробники - сценарії не «протікають» між тестами.

Переваги:

  • тест не знає про спосіб запиту - перехід з fetch на axios чи TanStack Query не ламає тести;
  • ті самі обробники працюють у браузері (через Service Worker) - для розробки фронтенду без готового бекенду, в Storybook і в браузерних тестах;
  • onUnhandledRequest: 'error' - тест падає на запиті, для якого немає обробника, замість тихого звернення в мережу.

Що варто знати:

  • відносні URL (/api/...) у середовищі jsdom розв'язуються відносно location тесту;
  • затримки й мережеві помилки - await delay(1000) і HttpResponse.error() для перевірки станів завантаження й обриву з'єднання;
  • перевіряти запит: тіло й заголовки читаються в обробнику (await request.json()), тож можна переконатися, що форма відправила правильні дані.

Докладніше в документації: Mock Service Worker

Схожі питання