Мокирование (mocking) — один из ключевых инструментов при тестировании компонентов React, особенно когда приложение зависит от внешних библиотек. Оно позволяет изолировать тестируемый компонент, заменяя реальные реализации зависимостей на контролируемые версии, что делает тесты предсказуемыми, быстрыми и устойчивыми к сторонним изменениям.
Основные цели мокирования внешних библиотек:
В React Testing Library чаще всего используются следующие методы:
Мокирование модулей через jest.mock
jest.mock позволяет перехватить импортируемый модуль и
заменить его кастомной реализацией.
import { render, screen } from '@testing-library/react';
import MyComponent from './MyComponent';
import axios from 'axios';
jest.mock('axios');
test('отрисовывает данные после запроса', async () => {
axios.get.mockResolvedValue({ data: { name: 'React' } });
render(<MyComponent />);
const nameElement = await screen.findByText(/React/i);
expect(nameElement).toBeInTheDocument();
});
В этом примере:
axios.get заменён на мок-функцию, возвращающую заранее
заданный объект.Мокирование функций и объектов внутри модуля Иногда нужно не весь модуль мокировать, а лишь отдельные функции:
import * as utils from './utils';
import { render, screen } from '@testing-library/react';
import MyComponent from './MyComponent';
jest.spyOn(utils, 'calculate').mockReturnValue(42);
test('использует мокированную функцию calculate', () => {
render(<MyComponent />);
expect(screen.getByText(/42/)).toBeInTheDocument();
});
jest.spyOn позволяет временно переопределить функцию
модуля.jest.mock, остальные функции
модуля остаются неизменными.Мокирование сторонних компонентов При
тестировании компонентов, использующих сторонние UI-библиотеки
(например, react-select или react-router-dom),
можно заменить их на простые моки:
jest.mock('react-router-dom', () => ({
...jest.requireActual('react-router-dom'),
Link: ({ children }) => <span>{children}</span>,
}));
В приложениях с асинхронными вызовами важно правильно мокировать промисы:
import api from './api';
jest.mock('./api');
api.fetchData.mockImplementation(() => Promise.resolve({ value: 10 }));
test('асинхронный мок', async () => {
render(<MyComponent />);
const element = await screen.findByText(/10/);
expect(element).toBeInTheDocument();
});
mockImplementation позволяет задать произвольное
поведение функции.await screen.findByText гарантирует, что
тест дождётся асинхронного результата.Важный момент: React Testing Library ориентирована на тестирование компонентов как пользователя, поэтому при мокировании следует сохранять максимально реалистичное поведение. Примеры хорошей практики:
fireEvent или
userEvent, даже если внутренние функции мокированы.afterEach(() => jest.clearAllMocks()), чтобы исключить
влияние предыдущих тестов.Мокирование внешних библиотек в React Testing Library позволяет
создавать надёжные и быстрые тесты, изолируя компонент от сторонних
факторов. Правильное использование jest.mock,
jest.spyOn и контролируемых промисов делает тестирование
устойчивым к изменениям зависимостей и минимизирует ошибки, связанные с
интеграцией. Важно балансировать между реалистичностью теста и его
предсказуемостью: мок должен упрощать тестирование, но не искажать
поведение компонента.