You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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包。

具体修改步骤:

  1. 卸载旧测试包:
npm uninstall @testing-library/react-hooks
  1. 安装最新测试库:
npm install --save-dev @testing-library/react
  1. 替换导入语句:
    把import { renderHook, act } from '@testing-library/react-hooks'改成:
import { renderHook, waitFor } from '@testing-library/react'
  1. 调整测试逻辑:
    不需要提前解构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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.22 19:07:36