Capítulo 42 de 80
Custom hooks wrapping useQuery/useMutation are tested with renderHook (React 18+, from @testing-library/react) plus a per-test QueryClientProvider wrapper, retries disabled so error-path tests don't time out waiting through exponential backoff.
QueryClient + QueryClientProvider wrapper per test (or clear a shared one between tests and disallow parallel test execution) so one test's cache state can't leak into another's.@testing-library/react-hooks + react-test-renderer; React 18+ gets renderHook directly from @testing-library/react, no extra package needed.retry: false in the test QueryClient's defaultOptions.queries to avoid tests timing out on the default 3-retry exponential backoff when testing an error path — this only applies as a fallback; a query with an explicit retry count still uses its own value.gcTime: set gcTime: Infinity (already the server default) if Jest complains about not exiting after a test run, when you've explicitly overridden gcTime to something finite in a test client.nock) rather than mocking queryFn itself, so the test also validates the real request shape; await waitFor(() => expect(result.current.isSuccess).toBe(true)) is the standard pattern for waiting on a hook's query to resolve before asserting on data.nock(...).persist().query(true)..., reading page from the mocked request URL), assert the first page loaded, call result.current.fetchNextPage(), then waitFor the accumulated data.pages to include both pages.const queryClient = new QueryClient({
defaultOptions: { queries: { retry: false } }, // avoid timeouts testing error paths
})
const wrapper = ({ children }) => (
<QueryClientProvider client={queryClient}>{children}</QueryClientProvider>
)
const { result } = renderHook(() => useCustomHook(), { wrapper })
await waitFor(() => expect(result.current.isSuccess).toBe(true))
expect(result.current.data).toEqual('Hello')
QueryClient, retries off, renderHook + waitFor to assert on resolved state.QueryClient when exercising an error path — otherwise the default exponential backoff makes the test slow or flaky against a timeout.nock or equivalent), not by stubbing queryFn — this actually validates the request your hook makes, not just its wiring.QueryClient per test (or explicitly clear + serialize test execution) — cache state is exactly the kind of hidden cross-test coupling that causes flaky suites.fetchNextPage/data.pages shape exercised in the infinite-scroll test example.