В тестах React с использованием React Testing Library состояние моков
напрямую влияет на изоляцию сценариев, предсказуемость ассертов и
корректность проверок побочных эффектов. Два ключевых инструмента Jest
для работы с этим состоянием — jest.clearAllMocks() и
jest.resetAllMocks(). Несмотря на схожесть названий, их
поведение принципиально различается.
jest.clearAllMocks():
очистка истории вызововjest.clearAllMocks() сбрасывает только
информацию о вызовах всех моков:
mock.calls)mock.results)mock.instances)При этом:
jest.mock() остаются
активнымиconst fetchData = jest.fn().mockResolvedValue({ data: [] });
fetchData();
fetchData();
expect(fetchData).toHaveBeenCalledTimes(2);
jest.clearAllMocks();
expect(fetchData).toHaveBeenCalledTimes(0);
// Реализация сохранена
await fetchData(); // по-прежнему возвращает { data: [] }
При тестировании компонентов часто требуется:
itТипичный сценарий:
beforeEach(() => {
jest.clearAllMocks();
});
Это позволяет писать тесты, где:
jest.resetAllMocks():
полный сброс моковjest.resetAllMocks() выполняет полную
перезагрузку всех моков:
jest.fn()Фактически, это эквивалент вызова .mockReset() для
каждого мока.
const fetchData = jest.fn().mockResolvedValue({ data: [] });
await fetchData();
jest.resetAllMocks();
await fetchData(); // возвращает undefined
jest.mock()Если модуль был замокан так:
jest.mock('../api', () => ({
fetchUser: jest.fn().mockResolvedValue({ name: 'Alex' }),
}));
После jest.resetAllMocks():
fetchUser остаётся функцией-мокомfetchUser() возвращает undefinedЭто критично при тестировании компонентов, которые ожидают конкретные данные:
render(<UserProfile />);
Компонент может упасть или перейти в некорректное состояние из-за отсутствия данных.
| Характеристика | clearAllMocks |
resetAllMocks |
|---|---|---|
| Очистка истории вызовов | ✔ | ✔ |
| Сброс реализации | ✘ | ✔ |
| Сброс возвращаемых значений | ✘ | ✔ |
| Повторная настройка моков требуется | ✘ | ✔ |
Подходит для beforeEach в RTL |
✔ | редко |
jest.spyOn)jest.spyOn создаёт мок поверх существующей
реализации.
const spy = jest.spyOn(console, 'error').mockImplementation(() => {});
clearAllMocks() очистит количество вызововresetAllMocks() удалит mockImplementation,
вернув исходную функциюЭто важно при проверке ошибок рендера:
expect(console.error).toHaveBeenCalled();
После resetAllMocks() такой ассерт может перестать
работать, если реализация больше не заглушена.
При тестировании асинхронного поведения:
api.fetchUsers.mockResolvedValueOnce([...]);
clearAllMocks() не удалит очередь
mockResolvedValueOnceresetAllMocks() очистит её
полностьюЭто может приводить к трудноотлавливаемым ошибкам, когда компонент в следующем тесте не получает ожидаемые данные.
beforeEach(() => {
jest.resetAllMocks();
});
При наличии глобальных моков API или кастомных хуков это приводит к:
undefined вместо данныхИспользование clearAllMocks() при тестах, которые
изменяют реализацию мока
(mockImplementationOnce), может оставить остаточное
состояние.
В таких случаях предпочтительнее:
mockReset() конкретного мокаbeforeEach(() => {
jest.clearAllMocks();
});
afterEach(() => {
someMock.mockReset();
});
Используется редко, обычно в низкоуровневых unit-тестах:
afterEach(() => {
jest.resetAllMocks();
});
React Testing Library ориентирован на поведение пользователя, а не на внутренние детали реализации. Стабильные моки — часть этого подхода. Частый полный сброс моков противоречит идее тестирования через интерфейс компонента, увеличивает шум и снижает читаемость тестов.
jest.clearAllMocks() поддерживает:
jest.resetAllMocks() — инструмент точечного применения,
требующий осознанного контроля.