Jest测试中react-query无法返回值,超时失败如何解决?
React Query测试超时问题排查与解决
我按照React Query官方文档写测试,但测试一直超时失败,组件始终处于loading状态——哪怕查询函数是立即返回结果的(不管返回Promise还是直接返回值都没区别)。
我的代码:
import React from 'react'; import { useInfiniteQuery, QueryClientProvider, QueryClient, useQuery } from '@tanstack/react-query' import { renderHook, act } from '@testing-library/react-hooks' function useCustomInfinuteHook() { // 没用到这个,但测试它也不行 return useInfiniteQuery([], () => { return Math.random(); }, { getNextPageParam() { return 2 } }) } export function useCustomHook() { return useQuery(['customHook'], async () => Promise.resolve('Hello')); } const queryClient = new QueryClient({ defaultOptions: { queries: { // ✅ 关闭重试 retry: false, }, }, }) const wrapper = ({ children }: any) => ( <QueryClientProvider client={queryClient}> {children} </QueryClientProvider> ); test("React Query?", async () => { const { result: { current }, waitForValueToChange, waitForNextUpdate } = renderHook(() => useCustomHook(), { // 用react-query provider包裹hook wrapper }) expect(current.isLoading).toBeTruthy(); await waitForValueToChange(() => current.isLoading, { timeout: 10000}); // 超时报错 expect(current.isLoading).toBeFalsy(); }, 10000)
报错信息:
● React Query? thrown: "Exceeded timeout of 10000 ms for a test. Use jest.setTimeout(newTimeout) to increase the timeout value, if this is a long-running test." 32 | 33 | > 34 | test("React Query?", async () => { | ^ 35 | const { result: { current }, waitForValueToChange } = renderHook(() => useCustomHook(), { 36 | // Wraps hook in a react-query provider 37 | wrapper at Object.<anonymous> (src/queries/testquery.test.tsx:34:1)
解决方案:
问题核心是**@testing-library/react-hooks旧包和React Query v4不兼容**。React Query v4官方推荐使用@testing-library/react自带的renderHook,而非单独的react-hooks包。
具体修改步骤:
- 卸载旧测试包:
npm uninstall @testing-library/react-hooks
- 安装最新测试库:
npm install --save-dev @testing-library/react
- 替换导入语句:
把import { renderHook, act } from '@testing-library/react-hooks'改成:
import { renderHook, waitFor } from '@testing-library/react'
- 调整测试逻辑:
不需要提前解构current(因为它不会自动更新引用),改用waitFor等待状态变化:
修改后的测试代码:
test("React Query?", async () => { const { result } = renderHook(() => useCustomHook(), { wrapper }) expect(result.current.isLoading).toBe(true); // 等待loading状态变为false await waitFor(() => expect(result.current.isLoading).toBe(false)); // 验证返回数据 expect(result.current.data).toBe('Hello'); })
额外注意事项:
- 确保React Query v4和React 18、
@testing-library/react(>=13.x)版本匹配; - 如果多个测试复用同一个
queryClient,建议在每个测试前重置状态,避免污染:
beforeEach(() => { queryClient.clear(); });
内容的提问来源于stack exchange,提问作者Slava Knyazev
相关产品推荐
相关产品推荐

