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

如何在Jest中断言Apollo useQuery查询已被调用指定次数?

解决useQuery调用次数断言失败的问题

错误原因

你当前的useQuery mock方式有误:你把useQuery设成了一个普通函数,它的返回值是jest.fn,但useQuery本身并不是Jest的mock/spy函数。而toHaveBeenCalledTimes这类匹配器只能作用于mock/spy函数,所以会抛出类型错误。

修复方案

方案1:修改jest.mock的定义,让useQuery本身成为mock函数

直接将useQuery赋值为jest.fn(),并返回组件渲染所需的hook返回值(比如loading、data等):

jest.mock('@apollo/client', () => {
  const actual = jest.requireActual('@apollo/client');
  return {
    ...actual,
    // 让useQuery本身是mock函数,同时返回组件需要的状态
    useQuery: jest.fn(() => ({
      loading: false,
      data: {}, // 根据你的业务场景替换为真实测试数据
      error: null
    })),
  };
});

const mountComponent = () => {
  return render(
    <MockedProvider mocks={mocks} addTypename={false}>
      <MyComponent />
    </MockedProvider>
  );
};

describe('MyComponent', () => {
  it('should only call the query 1 time', async () => {
    mountComponent();
    
    // 如果组件是同步渲染时调用useQuery,直接断言即可
    expect(useQuery).toHaveBeenCalledTimes(1);
    
    // 若useQuery是异步触发(比如依赖状态变化),再用waitFor包裹
    // await waitFor(() => {
    //   expect(useQuery).toHaveBeenCalledTimes(1);
    // });
  });
});

方案2:使用jest.spyOn来监听useQuery

如果你更倾向于保留原模块的其他实现,仅监听useQuery,可以用spyOn替代jest.mock:

import { useQuery } from '@apollo/client';

const mountComponent = () => {
  return render(
    <MockedProvider mocks={mocks} addTypename={false}>
      <MyComponent />
    </MockedProvider>
  );
};

describe('MyComponent', () => {
  let useQuerySpy;

  beforeEach(() => {
    // 创建spy并mock返回值
    useQuerySpy = jest.spyOn(require('@apollo/client'), 'useQuery')
      .mockReturnValue({ loading: false, data: {}, error: null });
  });

  afterEach(() => {
    // 测试后恢复原函数,避免影响其他测试
    useQuerySpy.mockRestore();
  });

  it('should only call the query 1 time', async () => {
    mountComponent();
    expect(useQuerySpy).toHaveBeenCalledTimes(1);
  });
});

关键注意点

  • 确保useQuery本身是Jest的mock/spy函数,而非返回mock函数的普通函数
  • 根据组件的渲染逻辑(同步/异步)决定是否需要waitFor
  • mock的返回值要匹配组件的依赖(比如组件依赖loading状态显示内容,就需要正确设置该字段)

内容的提问来源于stack exchange,提问作者que1326

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 05:55:15