renderHook — это метод, предоставляемый библиотекой @testing-library/react-hooks, который используется для тестирования кастомных хуков. Он позволяет рендерить хук в изолированной среде и получать доступ к его результатам и состоянию.
Основные функции renderHook:
- Рендеринг хуков: Рендерит кастомный хук в изолированной среде.
- Доступ к результатам: Предоставляет доступ к результатам хука через свойство
result. - Обновление состояния: Позволяет обновлять состояние хука с помощью метода
rerender. - Очистка: Позволяет выполнять очистку после теста с помощью метода
unmount.
Пример кастомного хука:
import { useState, useEffect } from "react";
function useCounter(initialCount) {
const [count, setCount] = useState(initialCount);
useEffect(() => {
const interval = setInterval(() => {
setCount((prevCount) => prevCount + 1);
}, 1000);
return () => clearInterval(interval);
}, []);
return count;
}
export default useCounter;Пример теста:
import { renderHook, act } from "@testing-library/react-hooks";
import useCounter from "./useCounter";
test("useCounter increments the count", () => {
// Рендерим хук с начальным значением
const { result } = renderHook(() => useCounter(0));
// Проверяем начальное состояние
expect(result.current).toBe(0);
// Обновляем состояние с помощью act
act(() => {
jest.advanceTimersByTime(1000);
});
// Проверяем обновленное состояние
expect(result.current).toBe(1);
// Обновляем состояние еще раз
act(() => {
jest.advanceTimersByTime(1000);
});
// Проверяем обновленное состояние
expect(result.current).toBe(2);
});Пояснение:
- Импорт
renderHookиact: ИмпортируйтеrenderHookиactиз@testing-library/react-hooks. - Рендеринг хука: Используйте
renderHookдля рендеринга хука с начальным значением. - Доступ к результатам: Используйте свойство
resultдля доступа к результатам хука. - Обновление состояния: Используйте
actдля обновления состояния хука. В данном случае, мы используемjest.advanceTimersByTimeдля продвижения времени и вызова эффектов. - Проверка обновленного состояния: Используйте
expectдля проверки обновленного состояния.
Дополнительные методы:
rerender: Позволяет перерендерить хук с новыми аргументами.unmount: Позволяет отмонтировать хук, что полезно для проверки очистки эффектов.
import { renderHook, act } from "@testing-library/react-hooks";
import useCounter from "./useCounter";
test("useCounter handles rerender and unmount", () => {
const { result, rerender, unmount } = renderHook(
({ initialCount }) => useCounter(initialCount),
{
initialProps: { initialCount: 0 },
},
);
expect(result.current).toBe(0);
act(() => {
jest.advanceTimersByTime(1000);
});
expect(result.current).toBe(1);
// Перерендерим хук с новым начальным значением
rerender({ initialCount: 5 });
expect(result.current).toBe(5);
// Отмонтируем хук
unmount();
// Проверяем, что интервал был очищен
act(() => {
jest.advanceTimersByTime(1000);
});
expect(result.current).toBe(5);
});