React-Query依赖查询单元测试及useUpdateTodo无Mock测试问题
问题1:React-Query依赖查询场景的单元测试写法
依赖查询的核心是前置查询完成后,后续逻辑才能基于其返回值执行,测试时要重点模拟前置查询的返回,并等待依赖值就绪:
- 先为测试搭建React-Query环境:用
QueryClientProvider包裹测试钩子,创建带默认配置的QueryClient(比如关闭重试、设置缓存时间为0) - 模拟前置查询的
queryFn,返回预期的测试数据 - 使用
waitFor或waitForNextUpdate等待前置查询完成,确保依赖值已生成 - 执行后续逻辑(比如触发mutation、检查依赖查询的状态),验证行为是否符合预期
问题2:不Mock useGetUserId时测试useUpdateTodo的方案
针对你提供的代码,核心是让useGetUserId内部的useQuery能正常返回用户ID,而非直接Mock这个钩子本身。以下是具体测试步骤和代码:
步骤说明
- 搭建React-Query测试上下文,确保
useQuery和useMutation能正常工作 - 模拟
getUserByEmail函数,让它返回包含有效ID的用户数据 - 使用
waitFor等待useGetUserId拿到userId后,再触发mutation - 验证axios的post请求是否携带了正确的userId
测试代码示例
import { renderHook, waitFor } from '@testing-library/react-hooks'; import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; import axios from 'axios'; import { useUpdateTodo } from './your-file-path'; import { getUserByEmail } from './your-user-service'; // Mock 依赖函数 jest.mock('./your-user-service', () => ({ getUserByEmail: jest.fn().mockResolvedValue({ id: 'test-user-123' }) })); jest.mock('axios'); describe('useUpdateTodo', () => { let queryClient; let wrapper; beforeEach(() => { // 创建测试用QueryClient queryClient = new QueryClient({ defaultOptions: { queries: { retry: false, cacheTime: 0 } } }); // 上下文包裹组件 wrapper = ({ children }) => ( <QueryClientProvider client={queryClient}>{children}</QueryClientProvider> ); }); it('should call axios.post with correct userId from useGetUserId', async () => { // 渲染钩子 const { result } = renderHook(() => useUpdateTodo(), { wrapper }); // 等待useGetUserId内部的useQuery完成,拿到userId await waitFor(() => { // 这里的queryKey要和useGetUserId中的一致,若email来自上下文需额外模拟 return queryClient.getQueryData(['user', 'test-email']) !== undefined; }); // 触发mutation const newTodo = { title: 'Test Todo' }; await result.current.mutateAsync(newTodo); // 验证请求参数 expect(axios.post).toHaveBeenCalledWith( '/todos', newTodo, 'test-user-123' ); }); });
关键注意点
- 若
useGetUserId中的email来自上下文(比如AuthContext),测试时需额外模拟该上下文,提供测试用的email值,否则queryKey不匹配会导致查询无法返回数据 waitFor是核心,确保userId就绪后再执行mutation,避免因异步未完成导致的测试失败- 不Mock
useGetUserId,而是Mock它依赖的getUserByEmail,能真实测试钩子的依赖逻辑
内容的提问来源于stack exchange,提问作者StanStanStan
相关产品推荐
相关产品推荐

