EasyTesting📖 Theory Question

How do you test custom hooks?

💡

Hint

renderHook from @testing-library/react — wraps the hook in a minimal component

Full Answer

import { renderHook, act } from '@testing-library/react';

// Hook under test
function useCounter(initial = 0) {
  const [count, setCount] = useState(initial);
  const increment = useCallback(() => setCount(c => c + 1), []);
  const reset = useCallback(() => setCount(initial), [initial]);
  return { count, increment, reset };
}

// Test
test('useCounter increments and resets', () => {
  const { result } = renderHook(() => useCounter(5));

  expect(result.current.count).toBe(5);

  act(() => { result.current.increment(); });
  expect(result.current.count).toBe(6);

  act(() => { result.current.reset(); });
  expect(result.current.count).toBe(5);
});

// Hook with context dependency — provide the context wrapper
test('useAuth returns user from context', () => {
  const wrapper = ({ children }) => (
    {children}
  );

  const { result } = renderHook(() => useAuth(), { wrapper });
  expect(result.current.user).toEqual(mockUser);
});
💡 Always wrap state updates in act(). RTL's userEvent does this automatically, but direct calls to hook functions need act() to flush React's update queue.

Practice this in a timed sprint →

5 free questions, no signup required

⚡ Start Sprint