Vue3单元测试Apollo useQuery 调用次数检测为0如何解决
单元测试useQuery调用次数校验始终返回0问题修复
问题复现代码
业务组件代码
export default defineComponent({ name: 'MyComponent', setup() { const { result: dataPagination } = useQuery(GET_DATA_PAGINATION, { skip: pagination.skip, take: pagination.take, }); // 其余业务逻辑 }, });
测试文件原代码
const mockUseQuery = jest.fn(); jest.mock('@vue/apollo-composable', () => ({ useQuery: () => ({ result: mockUseQuery }) })); describe('StoreType.vue', () => { let wrapper = null; beforeEach(() => { config = { global: { ...config.global, }, }; wrapper = mount(MyComponent, { ...config, shallow: true }); }); afterEach(() => { wrapper.unmount(); jest.resetAllMocks(); }); it('Fetch all store type by pagination', async() => { expect(wrapper.exists()).toBe(true); expect(mockQuery).toHaveBeenCalledTimes(1); }); });
错误原因
- mock逻辑写错:只把
useQuery返回值里的result赋值为mock函数,useQuery本身是普通匿名函数,没有调用统计能力 - 断言变量名错误:定义的mock变量叫
mockUseQuery,断言时写的是mockQuery,该变量未定义,调用计数永远为0
修复后代码
import { ref } from 'vue'; // 直接将useQuery声明为可统计调用的jest mock函数,按业务需求返回mock结果 const mockUseQuery = jest.fn(() => ({ result: ref(null), // 如有需要可以补充fetchMore、refetch等其他useQuery返回属性的mock })); jest.mock('@vue/apollo-composable', () => ({ useQuery: mockUseQuery })); describe('StoreType.vue', () => { let wrapper = null; beforeEach(() => { // 每个用例执行前清空之前的mock调用记录,避免用例间互相影响 jest.clearAllMocks(); config = { global: { ...config.global, }, }; wrapper = mount(MyComponent, { ...config, shallow: true }); }); afterEach(() => { wrapper.unmount(); jest.resetAllMocks(); }); it('按分页参数拉取门店类型数据', async() => { expect(wrapper.exists()).toBe(true); // 变量名和mock定义保持一致 expect(mockUseQuery).toHaveBeenCalledTimes(1); // 可选:校验调用传参是否符合预期 expect(mockUseQuery).toHaveBeenCalledWith(GET_DATA_PAGINATION, { skip: pagination.skip, take: pagination.take, }); }); });
补充说明:如果
useQuery不是在setup同步阶段调用(比如放在watch、异步回调、点击事件触发逻辑里),断言前需要加await flushPromises()等待所有异步任务执行完成,否则还是会出现计数为0的情况。
内容的提问来源于stack exchange,提问作者kosterz
相关产品推荐
相关产品推荐

