如何用RTL测试使用react-query的React自定义Hook并包裹Provider?
报错原因
useQuery 必须运行在 QueryClientProvider 注入的上下文环境中,直接调用renderHook渲染自定义Hook时,默认不会自动包裹该Provider,因此抛出「未设置QueryClient」的错误。
修复方式
renderHook 原生支持wrapper配置项,可自定义包裹组件为待测试Hook注入上下文,具体实现步骤如下:
- 第一步:创建测试专用的QueryClient实例,关闭测试环境下的查询重试逻辑,避免重试机制干扰测试断言;注意每个测试用例需单独创建实例,防止测试间的缓存数据互相污染。
import { QueryClient } from 'react-query' const createTestQueryClient = () => new QueryClient({ defaultOptions: { queries: { retry: false, }, }, })
- 第二步:调用
renderHook时传入wrapper配置,将测试用QueryClient通过Provider注入上下文:
import { renderHook } from '@testing-library/react-hooks' import { QueryClientProvider } from 'react-query' import { useFetchSomething } from './your-hook-path' test('useFetchSomething 逻辑测试', () => { const testQueryClient = createTestQueryClient() const { result } = renderHook(() => useFetchSomething(), { wrapper: ({ children }) => ( <QueryClientProvider client={testQueryClient}> {children} </QueryClientProvider> ) }) // 后续编写对应断言逻辑即可 })
复用优化
如果项目中有多个依赖react-query的Hook测试,可以将wrapper逻辑抽为公共测试工具函数,避免重复编写包裹代码:
// 测试公共工具文件 test-utils.js export const createQueryWrapper = () => { const testQueryClient = createTestQueryClient() return ({ children }) => ( <QueryClientProvider client={testQueryClient}> {children} </QueryClientProvider> ) } // 其他测试文件中直接引入使用 const { result } = renderHook(() => useFetchSomething(), { wrapper: createQueryWrapper() })
内容的提问来源于stack exchange,提问作者Martin Rützy
相关产品推荐
相关产品推荐

