Jest · Unit tests that survive refactors
How do you test custom React hooks?
Short answer
Use renderHook from Testing Library to mount a hook, then act on result, rerender and unmount. Prefer testing the hook through real UI when its behaviour is only meaningful in a component.
A custom hook is just a function that uses other hooks, so it needs a React renderer to run. renderHook creates a small test component internally and exposes the hook's return value through result.current. That makes it possible to test state transitions and cleanup without inventing a full component.
import { act, renderHook } from "@testing-library/react";
import { useCounter } from "./useCounter";
test("increments and resets", () => {
const { result } = renderHook(() => useCounter(3));
act(() => result.current.increment());
expect(result.current.count).toBe(4);
act(() => result.current.reset());
expect(result.current.count).toBe(3);
});What renderHook gives you
result.currentfor the latest returned valuererenderto change props and exercise updatesunmountto verify cleanup and cancellationactorwaitForto wrap state updates and async effects
Prefer a component test when the hook is inseparable from rendering, such as a hook that returns props for a form. renderHook is best for reusable logic with a clear input and output: pagination, debouncing, media queries, form state machines. If the hook needs a provider, pass a wrapper to renderHook.
Follow-ups you should expect
Interviewers use these to check whether the first answer was understanding or memorisation.
- 1How do you test a hook that needs a context provider?
- 2How do you verify that an effect cleans up?
- 3When is a component test better than renderHook?
- 4Why must state updates in a hook test be wrapped in act?
Say it in the interview
renderHook mounts a tiny component so the hook runs in a real React renderer. I read result.current, call the exposed actions inside act, and can rerender with new props or unmount to check cleanup. For hooks that are tightly coupled to UI, I test through a component instead. I use it mainly for reusable logic with a clear input and output.
Use this as a model, not a script. Saying it in your own words is what makes it survive follow-up pressure.
Related questions
Reading is step one
Now say it out loud.
Understanding an answer and delivering it under pressure are different skills. Rehearse this topic in a live Jest mock interview and get scored feedback on depth, clarity and confidence.