使用react-testing-library测试react-query触发的getRecipes接口调用
解决react-testing-library监视react-query调用的getRecipes函数未被检测到的问题
1. 确保正确监视函数的导出实例
问题最常见的原因是spyOn的目标不是组件实际调用的那个函数实例,要根据导出方式调整:
- 命名导出场景:
组件中如果是export const getRecipes = () => {...},测试里要从模块的命名导出上spyOn:// 测试文件 import * as recipeApi from '../services/recipeApi'; // 替换成你的api模块路径 test('LoggedIn组件加载时调用getRecipes', async () => { // 监视命名导出的getRecipes,并mock返回值 const spy = jest.spyOn(recipeApi, 'getRecipes').mockResolvedValue([]); // 渲染组件... }); - 默认导出场景:
组件中如果是export default getRecipes,不能直接spyOn导入的默认函数(因为导入的是副本),要spyOn模块的default属性:// 测试文件 import * as recipeApi from '../services/recipeApi'; test('LoggedIn组件加载时调用getRecipes', async () => { const spy = jest.spyOn(recipeApi, 'default').mockResolvedValue([]); // 渲染组件... });
2. 等待react-query异步查询完成
react-query的useQuery是异步执行的,直接断言会因为时机问题失败,必须用waitFor等待查询完成:
import { render, waitFor } from '@testing-library/react'; import { QueryClient, QueryClientProvider } from 'react-query'; import LoggedIn from '../LoggedIn'; import * as recipeApi from '../services/recipeApi'; test('LoggedIn组件加载时调用getRecipes', async () => { const spy = jest.spyOn(recipeApi, 'getRecipes').mockResolvedValue([]); // 创建QueryClient,禁用缓存避免干扰测试 const queryClient = new QueryClient({ defaultOptions: { queries: { cacheTime: 0, staleTime: 0, retry: 0, // 禁用重试,避免多次调用干扰断言 }, }, }); render( <QueryClientProvider client={queryClient}> <LoggedIn /> </QueryClientProvider> ); // 等待查询执行完成后断言 await waitFor(() => { expect(spy).toHaveBeenCalledTimes(1); }); });
3. 排查模块缓存或重复导入问题
如果上述步骤都无效,检查组件和测试中导入getRecipes的路径是否完全一致(比如避免../api和./api的差异),确保两者引用的是同一个函数实例。可以在组件和测试中分别打印console.log(getRecipes),对比输出的引用地址是否相同。
内容的提问来源于stack exchange,提问作者Jonathan Gafar
相关产品推荐
相关产品推荐

