译零 TransZero · TanStack Query 中文文档
主站

测试

更新于 2026-11-02 Solid 查看英文原文 ↗

Solid Query 通过基础原语(primitives)工作——这些原语要么是我们提供的,要么是你编写的、封装了这些原语的自定义原语。

这些原语从 QueryClientProvider 中读取 QueryClient,因此必须在 QueryClientProvider 下运行。你可以使用 Solid Testing Library 提供的 renderHook 来编写它们的单元测试。

通过运行以下命令安装:

Shell
1npm install @solidjs/testing-library --save-dev

我们的第一项测试

安装完成后,即可编写一个简单测试。假设有如下自定义原语:

TypeScript
1export function useCustomQuery() {2  return useQuery(() => ({ queryKey: ['customQuery'], queryFn: () => 'Hello' }))3}

我们可以为其编写如下测试:

TypeScript
1import { renderHook, waitFor } from '@solidjs/testing-library'2import { QueryClient, QueryClientProvider } from '@tanstack/solid-query'3import type { ParentProps } from 'solid-js'4 5const queryClient = new QueryClient()6const wrapper = (props: ParentProps) => (7  <QueryClientProvider client={queryClient}>8    {props.children}9  </QueryClientProvider>10)11 12const { result } = renderHook(() => useCustomQuery(), { wrapper })13 14await waitFor(() => expect(result.isSuccess).toBe(true))15 16expect(result.data).toEqual('Hello')

注意,我们提供了一个自定义包装器,用于构建 QueryClient 和 QueryClientProvider。这有助于确保我们的测试完全与其他测试隔离。

该包装器可以只编写一次,但若如此,则需确保每次测试前都清空 QueryClient,且测试不能并行执行;否则,一个测试会影响其他测试的结果。

result 是 useQuery 返回的响应式对象,而非快照,因此应在等待之后再读取其属性,而不是在最开始就对其进行解构。解构所得的值会保持其被读取时的值。

waitFor 会重试断言直至其通过,这对等待真实请求的查询函数有效。当查询函数等待定时器时,你可以改用模拟定时器(fake timers)并手动推进它们,例如在 Vitest 中使用 vi.advanceTimersByTimeAsync。请在 afterEach 中恢复真实定时器,以确保即使断言失败,定时器也能被正确恢复:

TypeScript
1beforeEach(() => {2  vi.useFakeTimers()3})4 5afterEach(() => {6  vi.useRealTimers()7})8 9it('should resolve the delayed query', async () => {10  const { result } = renderHook(11    () =>12      useQuery(() => ({13        queryKey: ['delayed'],14        queryFn: () =>15          new Promise((resolve) => setTimeout(() => resolve('Hello'), 1000)),16      })),17    { wrapper },18  )19 20  await vi.advanceTimersByTimeAsync(1000)21 22  expect(result.data).toEqual('Hello')23})

对于更复杂的原语,直接测试使用它们的组件可能更简便:使用 Solid Testing Library 的 render 在相同的 QueryClientProvider 下渲染该组件,并对其渲染结果进行断言。

关闭重试

该库默认启用三次指数退避重试(retry),这意味着如果你希望测试一个出错的查询,测试很可能会超时。最简单的禁用重试方式是通过你传给 QueryClientProvider 的 QueryClient 进行配置。我们来扩展上面的例子:

TypeScript
1const queryClient = new QueryClient({2  defaultOptions: {3    queries: {4      // ✅ turns retries off5      retry: false,6    },7  },8})9const wrapper = (props: ParentProps) => (10  <QueryClientProvider client={queryClient}>11    {props.children}12  </QueryClientProvider>13)

这会将组件树中所有查询的默认重试次数设为“零次”。需要注意的是,该设置仅在你的实际 useQuery 未显式指定重试次数时才生效;如果某个查询明确设置了 5 次重试,该设置仍将优先于默认值,因为默认值仅作为后备方案使用。

使用 Jest 将 gcTime 设为 Infinity

如果你使用 Jest,可将 gcTime 设为 Infinity,以避免出现 “Jest did not exit one second after the test run completed” 错误提示。这是服务端的默认行为;仅当你显式设置了 gcTime 时,才需要手动设置此项。

本页为 TanStack Query 文档(Solid 版)的非官方中文翻译,原文由上游团队维护,遵循 MIT 许可。 译文如有偏差,以英文原文为准。

译自上游 59d11de