React Query调用onSuccess的单元测试:handleRefetch断言失败
解决TestComponent中refetch调用断言失败的问题
1. 确认测试中正确传入mock的refetch函数
必须在渲染组件时,把mock的refetch函数作为prop传入,否则组件内部无法调用到这个mock函数:
const mockedHandleRefetch = jest.fn(); // 关键:将mock函数传递给组件的refetch属性 render(<TestComponent refetch={mockedHandleRefetch} />, { wrapper });
2. 配置React Query测试环境
如果使用react-query的useMutation,测试时必须用QueryClientProvider包裹组件,否则mutation的生命周期(包括onSuccess)无法正常触发:
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; // 创建QueryClient,关闭重试避免测试延迟 const queryClient = new QueryClient({ defaultOptions: { queries: { retry: false }, mutations: { retry: false }, }, }); // 定义包裹组件的wrapper const wrapper = ({ children }) => ( <QueryClientProvider client={queryClient}>{children}</QueryClientProvider> ); // 渲染组件时传入wrapper render(<TestComponent refetch={mockedHandleRefetch} />, { wrapper });
3. 验证Nock请求拦截是否匹配
检查Nock的拦截规则是否和组件实际发送的请求完全一致:
- 请求路径、方法是否与组件中的请求逻辑匹配
- 如果组件发送了特定请求体,Nock需要匹配body才能触发成功响应
可以添加断言验证Nock是否被正确触发:
// 验证Nock的拦截规则是否被执行 expect(nock.isDone()).toBe(true);
如果这个断言失败,说明请求没被Nock拦截,mutation的onSuccess不会执行,自然不会调用refetch。
4. 简化测试中的Act调用
userEvent的click、type方法已经自动处理了React的act包裹,不需要手动嵌套act,否则可能导致时序问题:
// 错误写法 await act(async () => { await user.click(saveButton) }); // 正确写法 await user.click(saveButton);
5. 延长waitFor的超时时间(可选)
默认waitFor的超时时间是1000ms,如果mutation的onSuccess触发较慢,可以延长超时时间:
await waitFor(() => { expect(mockedHandleRefetch).toBeCalledTimes(1); }, { timeout: 3000 });
6. 检查组件内部handleRefetch的实现
确保组件内部的handleRefetch确实调用了传入的refetch prop,没有额外的条件判断或错误绑定:
// 组件内部正确示例 const TestComponent = ({ refetch }) => { const handleRefetch = () => { refetch(); // 直接调用props传入的refetch }; // ...其他逻辑 };
内容的提问来源于stack exchange,提问作者syn
相关产品推荐
相关产品推荐

