Jest: моки (jest.fn, jest.mock)
jest.fnсоздаёт mock-функцию с отслеживанием вызовов, аjest.mockполностью заменяет модуль на автоматический или ручной mock — основа изоляции unit-тестов.
Зачем нужно
Mock позволяет изолировать тестируемый код от внешних зависимостей: HTTP-запросов, базы данных, файловой системы. Тест становится быстрым, предсказуемым и не зависит от окружения. Без моков unit-тест превращается в integration-тест.
Где используется
- Замена API-клиентов (
axios,fetch) в unit-тестах - Изоляция сервисов друг от друга в модульных тестах
- Контроль возвращаемых значений для тестирования разных сценариев
- Проверка, что зависимость была вызвана с нужными аргументами
Основной контент
jest.fn — mock-функция
const mockCallback = jest.fn;
// Задать возвращаемое значение
mockCallback.mockReturnValue(42);
mockCallback.mockReturnValueOnce('first call').mockReturnValueOnce('second');
// Задать реализацию
mockCallback.mockImplementation((x) => x * 2);
// Задать Promise
mockCallback.mockResolvedValue({ data: });
mockCallback.mockRejectedValue(new Error('Network error'));
// Проверки
expect(mockCallback).toHaveBeenCalled();
expect(mockCallback).toHaveBeenCalledTimes(2);
expect(mockCallback).toHaveBeenCalledWith('arg1', 'arg2');
jest.mock — мокирование модуля
// __mocks__/axios.js НЕ нужен — jest.mock заменяет автоматически
jest.mock('axios');
import axios from 'axios';
import { getUser } from './userService';
test('получает пользователя', async () => {
axios.get.mockResolvedValue({ data: { id: 1, name: 'Alice' } });
const user = await getUser(1);
expect(axios.get).toHaveBeenCalledWith('/api/users/1');
expect(user.name).toBe('Alice');
});
Частичный мок модуля
jest.mock('./utils', () => ({
...jest.requireActual('./utils'), // оставляем реальные методы
formatDate: jest.fn( => '01.01.2024'), // мокируем только этот
}));
Ручной mock (mocks)
src/
services/
api.js
__mocks__/
api.js ← ручной mock
// __mocks__/api.js
module.exports = {
getUser: jest.fn.mockResolvedValue({ id: 1, name: 'Mock User' }),
};
// В тесте
jest.mock('./services/api'); // Jest подхватит __mocks__/api.js
Сброс и очистка моков
afterEach(() => {
jest.clearAllMocks; // сбрасывает историю вызовов
// jest.resetAllMocks — сбрасывает историю + реализацию
// jest.restoreAllMocks — восстанавливает spyOn оригиналы
});
Частые ошибки
jest.mockне в верхнем уровне файла — Jest поднимаетjest.mockвверх (hoisting), но если написать внутри функции, поведение непредсказуемо- Забытый
clearAllMocks— моки накапливают историю между тестами и ломаютtoHaveBeenCalledTimes - Мок без
mockResolvedValueдля async — если mock-функция не возвращает Promise, await вернётundefined - Мокирование defaultExport ES-модуля — нужен
{ default: mockFn }или__esModule: true