You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.30 22:54:25