Перейти к содержимому

52. Тестирование хуков

Хуки нельзя вызывать вне функциональных компонентов, поэтому для их тестирования используется специальная утилита renderHook.

Icon: Anchor (Якорь)

renderHook создает временный компонент-обертку, вызывает внутри него ваш хук и предоставляет доступ к возвращаемым значениям через объект result.

graph LR
Test[Тест] -->|renderHook| Wrapper[Временный компонент]
Wrapper -->|вызов| Hook[Кастомный хук]
Hook -->|обновление| result[result.current]
Test -->|act| Action[Действие внутри хука]
Action --> Hook

Хук:

export function useCounter() {
const [count, setCount] = useState(0);
const increment = () => setCount((c) => c + 1);
return { count, increment };
}

Тест:

import { renderHook, act } from '@testing-library/react';
import { useCounter } from './useCounter';
test('должен увеличивать счетчик', () => {
const { result } = renderHook(() => useCounter());
expect(result.current.count).toBe(0);
act(() => {
result.current.increment();
});
expect(result.current.count).toBe(1);
});

Любые действия, приводящие к обновлению состояния в React (клики, изменение стейта в хуке), в тестах должны быть обернуты в act(...). Это гарантирует, что все обновления будут применены до того, как вы начнете проверять результат (assertions).

Для хуков, которые загружают данные, используйте waitFor:

const { result } = renderHook(() => useUser(1));
await waitFor(() => expect(result.current.isLoaded).toBe(true));

Попробуйте примеры в интерактивном редакторе: