Доки по разработке
This project is maintained by teniryte
TanStack Query легко тестируется, если вы делаете две вещи:
QueryClient на каждый тестimport { QueryClient, QueryClientProvider } from '@tanstack/react-query'
export function createTestQueryClient() {
return new QueryClient({
defaultOptions: {
queries: {
retry: false,
},
mutations: {
retry: false,
},
},
})
}
export function createWrapper() {
const queryClient = createTestQueryClient()
return function Wrapper({ children }: { children: React.ReactNode }) {
return (
<QueryClientProvider client={queryClient}>
{children}
</QueryClientProvider>
)
}
}
renderHookДля React 18+ используйте renderHook из @testing-library/react.
import { renderHook, waitFor } from '@testing-library/react'
test('loads todos', async () => {
const wrapper = createWrapper()
const { result } = renderHook(() => useTodos(), { wrapper })
await waitFor(() => expect(result.current.isSuccess).toBe(true))
expect(result.current.data).toEqual([{ id: '1', title: 'Learn Query' }])
})
По умолчанию query ретраятся 3 раза. Это:
Поэтому retry: false в test client почти всегда разумный дефолт.
gcTimeЕсли вы явно меняете gcTime и используете Jest, иногда полезно держать gcTime: Infinity, чтобы избежать проблем с незавершёнными таймерами. В серверном окружении это и так значение по умолчанию.
Имеет смысл тестировать:
Подходы:
MSW чаще всего удобнее для React-приложенийnock подходит для node-based integration scenariosГлавное правило: не мокайте TanStack Query, мокайте сеть или API-слой.
test('loads next page', async () => {
const wrapper = createWrapper()
const { result } = renderHook(() => useFeed(), { wrapper })
await waitFor(() => expect(result.current.isSuccess).toBe(true))
await result.current.fetchNextPage()
await waitFor(() =>
expect(result.current.data.pages).toHaveLength(2),
)
})
Проверяйте два сценария:
Это особенно важно для финансовых, административных и collaborative экранов.
QueryClient.useQuery и useMutation, если можно мокнуть сеть.