Зачем нужно мокировать HTTP запросы

В тестировании компонентов React ключевым аспектом является управление внешними зависимостями. Одной из таких зависимостей являются HTTP-запросы к API. Мокирование HTTP-запросов позволяет полностью контролировать поведение приложения в тестах, обеспечивая стабильность, предсказуемость и высокую скорость выполнения тестов.

Контроль над результатами запросов

Когда компонент взаимодействует с внешним API, поведение приложения зависит от ответа сервера. Использование реального API в тестах приводит к нестабильности: сервер может быть недоступен, данные изменятся, а время отклика может отличаться. Мокирование позволяет:

  • возвращать заранее определённые данные;
  • проверять реакцию компонента на различные сценарии (успешный ответ, ошибка, пустой результат);
  • избегать зависимости от состояния внешнего сервера.

Пример использования jest.mock для мока fetch:

global.fetch = jest.fn(() =>
  Promise.resolve({
    json: () => Promise.resolve({ id: 1, name: 'Test User' }),
  })
);

Ускорение тестов

Запросы к реальным серверам замедляют выполнение тестов, особенно при большом наборе компонентов. Мокирование полностью устраняет сетевые задержки, позволяя тестам выполняться практически мгновенно. Это критично для CI/CD процессов, где время выполнения тестов влияет на скорость развертывания.

Сценарное тестирование

Мокирование HTTP-запросов позволяет создавать разнообразные сценарии:

  • Успешный ответ: компонент корректно отображает данные.
  • Ошибка сервера: компонент показывает сообщение об ошибке или fallback UI.
  • Пустой ответ: компонент обрабатывает отсутствие данных без поломки интерфейса.

Пример мокирования ошибки:

global.fetch = jest.fn(() =>
  Promise.reject(new Error('Network Error'))
);

Тестирование компонента с этим мокированием проверяет, что UI реагирует на ошибки корректно:

import { render, screen, waitFor } from '@testing-library/react';
import UserProfile from './UserProfile';

test('показывает сообщение об ошибке при сбое запроса', async () => {
  render(<UserProfile />);
  await waitFor(() => expect(screen.getByText(/ошибка/i)).toBeInTheDocument());
});

Повторяемость и предсказуемость тестов

Без моков один и тот же тест может давать разные результаты из-за изменений на сервере или нестабильной сети. Мокирование гарантирует:

  • Консистентные результаты: данные всегда одинаковы.
  • Повторяемость: тест можно запускать бесконечное число раз без влияния внешних факторов.
  • Изоляцию: тест проверяет только логику компонента, а не работу стороннего сервиса.

Интеграция с React Testing Library

React Testing Library ориентирована на тестирование компонентов «как пользователь», но при этом взаимодействие с сетью необходимо контролировать. Использование моков позволяет интегрировать сетевые сценарии без изменения логики компонент. Комбинируя jest.mock или msw (Mock Service Worker) с @testing-library/react, можно тестировать:

  • рендеринг данных после успешного запроса;
  • состояние загрузки (loading) до завершения запроса;
  • отображение ошибок при сбое запроса.

Пример с msw:

import { rest } from 'msw';
import { setupServer } from 'msw/node';
import { render, screen } from '@testing-library/react';
import UserProfile from './UserProfile';

const server = setupServer(
  rest.get('/api/user', (req, res, ctx) => {
    return res(ctx.json({ id: 1, name: 'Test User' }));
  })
);

beforeAll(() => server.listen());
afterEach(() => server.resetHandlers());
afterAll(() => server.close());

test('отображает данные пользователя', async () => {
  render(<UserProfile />);
  const userName = await screen.findByText(/Test User/i);
  expect(userName).toBeInTheDocument();
});

Использование msw обеспечивает более реалистичное мокирование, имитируя сетевые запросы на уровне протокола HTTP, что особенно полезно при сложных сценариях.

Вывод

Мокирование HTTP-запросов — фундаментальная практика при тестировании компонентов React. Оно обеспечивает контроль над внешними зависимостями, ускоряет тесты, позволяет проверять все сценарии работы с данными и гарантирует повторяемость результатов. Совмещение моков с React Testing Library делает тесты надежными, предсказуемыми и сосредоточенными исключительно на поведении компонентов.