new·The score now tells you which way it movedA brain's exam only ever grows: its own material writes questions, and so does every question a real caller asked and did not get answered. The score is a percentage over that growing set, so a brain that learned more could post a smaller number — and this week three did. One of them answered two MORE questions than the week before and showed eighteen points less. Printed as a single percentage, that reads as decline to a reader and as punishment to anyone who contributes material.all news →
mozg.beta
Sign in

TanStack Query · React · all subjects

testing

12 notes, read out of this brain and free to use. Each one was extracted from a source and is re-checked against its exam.

React Hooks Testing Library installation for React 17

For React 17 or earlier, use the React Hooks Testing Library library to write unit tests for custom hooks. Install with: npm install @testing-library/react-hooks react-test-renderer --save-dev. The react-test-renderer library is a peer dependency and must correspond to your React version.

renderHook in React 18+

When using React 18 or later, renderHook is available directly through the @testing-library/react package, and @testing-library/react-hooks is no longer required.

Test custom hook with QueryClientProvider wrapper

When testing a custom hook that uses useQuery, wrap it with a QueryClientProvider in a custom wrapper component to ensure test isolation. Create a new QueryClient instance for each test. Example: const queryClient = new QueryClient(); 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('expectedValue');

Shared QueryClient wrapper requires clearing between tests

If you write a QueryClient wrapper only once for multiple tests, you must ensure that the QueryClient gets cleared before every test, and tests must not run in parallel. Otherwise, one test will influence the results of others.

Disable retries in tests

React Query defaults to three retries with exponential backoff, which causes tests to timeout when testing erroneous queries. Disable retries via the QueryClient configuration: const queryClient = new QueryClient({ defaultOptions: { queries: { retry: false } } }). This only works if the actual useQuery has no explicit retries set, as explicit retries take precedence over defaults.

Set gcTime to Infinity with Jest

When using Jest, set gcTime to Infinity to prevent the 'Jest did not exit one second after the test run completed' error message. This is the default behavior on the server and is only necessary if you are explicitly setting a gcTime.

Testing network calls with nock

Use nock to mock and test network requests made by React Query. Set up mock responses before rendering the hook, then use waitFor to wait for the query status to indicate success before asserting on the data.

Example: Testing network calls with nock

const queryClient = new QueryClient(); const wrapper = ({ children }) => (<QueryClientProvider client={queryClient}>{children}</QueryClientProvider>); const expectation = nock('http://example.com').get('/api/data').reply(200, { answer: 42 }); const { result } = renderHook(() => useFetchData(), { wrapper }); await waitFor(() => expect(result.current.isSuccess).toBe(true)); expect(result.current.data).toEqual({ answer: 42 });

Testing infinite queries with pagination

Use nock with .persist() and .query(true) to mock API responses that change based on query parameters. Parse the uri parameter to extract pagination values and return different mock data for each page.

Example: Testing infinite queries with nock

const expectation = nock('http://example.com').persist().query(true).get('/api/data').reply(200, (uri) => { const url = new URL(`http://example.com${uri}`); const { page } = Object.fromEntries(url.searchParams); return generateMockedResponse(page); }); const { result } = renderHook(() => useInfiniteQueryCustomHook(), { wrapper }); await waitFor(() => expect(result.current.isSuccess).toBe(true)); expect(result.current.data.pages).toStrictEqual(generateMockedResponse(1)); result.current.fetchNextPage(); await waitFor(() => expect(result.current.data.pages).toStrictEqual([...generateMockedResponse(1), ...generateMockedResponse(2)])); expectation.done();

React 18 waitFor semantics changed

When using React 18, the semantics of waitFor have changed compared to earlier versions.

Alternative testing setup with mock-service-worker

An alternative to nock for testing is mock-service-worker. See the article 'Testing React Query' by TkDodo for additional tips and alternative setup approaches.

Give your agent this brain