Skip to content

Testing & Debugging in TanStack React Query

Cache invalidation is one of the trickiest parts of state management. Ensuring it's done correctly requires both debugging tools and reliable tests.

Developer Tools Integration

For Chrome, Firefox, and Edge users: Third-party browser extensions are available for debugging TanStack Query directly in browser DevTools. These provide the same functionality as the framework-specific devtools packages:

React Query provides DevTools to help visualize queries, cache states, and invalidation in real time.

import {ReactQueryDevtools} from '@tanstack/react-query-devtools'

function App() {
    return (
        <QueryClientProvider client={queryClient}>
            <MyComponents/>
            <ReactQueryDevtools initialIsOpen={false}/>
        </QueryClientProvider>
    )
}

With DevTools, you can:

  • Inspect query keys and their current state
  • See which queries are marked invalidated
  • Debug the lifecycle of queries and mutations

Writing Tests for Cache Invalidation

To ensure correctness, write tests that explicitly check query cache behavior after mutations.

Test Utilities

// test-utils.ts
export function createTestQueryClient() {
    return new QueryClient({
        defaultOptions: {
            queries: {retry: false},
        },
        logger: {
            log: console.log,
            warn: console.warn,
            error: () => {
            }, // suppress errors during tests
        },
    })
}

Example Test

// invalidation.test.ts
test('invalidates todo list after adding new todo', async () => {
    const queryClient = createTestQueryClient()

    // prefetch existing todos
    await queryClient.prefetchQuery({
        queryKey: queryKeys.todos.all,
        queryFn: () => ['todo1', 'todo2'],
    })

    // simulate mutation that adds a new todo
    await queryClient.executeMutation({
        mutationFn: () => Promise.resolve('todo3'),
        onSuccess: () => {
            queryClient.invalidateQueries({queryKey: queryKeys.todos.all})
        },
    })

    // assert cache invalidation
    expect(queryClient.getQueryState(queryKeys.todos.all)?.isInvalidated).toBe(true)
})

References