React 18项目中用nock+react-query测试自定义hook遇问题求助
React Query自定义Hook测试:result.current undefined且一直处于loading状态的解决办法
核心原因分析
1. result.current 出现undefined的原因
初始渲染阶段React尚未完成Hook执行时,直接访问result.current会拿到undefined,但如果在waitFor回调内仍出现该问题,大概率是你的createQueryProviderWrapper未正确配置QueryClientProvider——比如没有创建有效的QueryClient实例,导致React Query上下文未注入,Hook无法正常初始化。
2. 查询一直处于loading的关键原因
最常见的问题是nock域名与实际请求域名不匹配:
你的getUserProfileAPI中使用fetch('v1/me')是相对路径,实际请求会发送到测试环境默认域名(如http://localhost:3000/v1/me),但你用nock模拟的是https://api.example.com,导致nock无法拦截请求,真实请求挂起,查询一直停留在loading状态。
3. 配置中遗漏的关键点
- 未给
QueryClient配置测试友好的参数(如关闭重试) - nock域名与实际请求域名不匹配
- 测试中仅打印日志未添加断言,无法触发
waitFor的等待逻辑
具体修复步骤
步骤1:修正nock的域名匹配
如果getUserProfileAPI使用相对路径,修改nock匹配测试环境域名:
// 匹配测试环境默认域名(示例为localhost:3000) nock("http://localhost:3000") .get("/v1/me") .reply(200, { data: { id: 1, firstName: "value from the api", }, });
或者修改getUserProfileAPI使用绝对路径,确保和nock域名一致:
// getUserProfileAPI中使用绝对路径 export const getUserProfileAPI = () => { return fetch("https://api.example.com/v1/me").then(res => res.json()); };
步骤2:确保createQueryProviderWrapper配置正确
检查测试工具函数是否正确创建QueryClient并提供上下文,建议关闭重试避免测试超时:
// @/test/index.js import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; import { ReactNode } from 'react'; export const createQueryProviderWrapper = () => { const queryClient = new QueryClient({ defaultOptions: { queries: { retry: false, // 测试时关闭重试 refetchOnWindowFocus: false, }, }, }); return ({ children }: { children: ReactNode }) => ( <QueryClientProvider client={queryClient}>{children}</QueryClientProvider> ); };
步骤3:修改测试逻辑,添加断言
在waitFor中添加断言,确保等待到查询成功,而非仅打印日志:
test("should fetch user profile and have correct nickname", async () => { nock("https://api.example.com") .get("/v1/me") .reply(200, { data: { id: 1, firstName: "value from the api", }, }); const { result } = setupHook(); // 等待查询成功 await waitFor(() => { expect(result.current.isSuccess).toBe(true); }); // 断言数据正确性 expect(result.current.data.data.firstName).toBe("value from the api"); });
额外检查点
- 确认
getUserProfileAPI返回有效Promise,无语法错误或未处理异常 - 测试前添加
nock.cleanAll()清理旧模拟,避免干扰 - 若使用Jest,确保测试环境支持fetch(可安装
whatwg-fetch并在setupFiles中引入)
内容的提问来源于stack exchange,提问作者Michael Luo
相关产品推荐
相关产品推荐

