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

如何用Jest+React Testing Library测试Query的onCompleted等回调

如何触发Apollo Query组件的onCompleted回调并测试其中的逻辑?

没问题!我来帮你理清怎么测试这个onCompleted回调里的if逻辑。作为Jest和React Testing Library的新手,你只需要关注两个核心点:让mock数据满足触发条件,然后等待回调执行并验证结果。


第一步:调整Mock数据,满足onCompleted的if判断条件

你的onCompleted回调里的逻辑是当dataVaras.varas_competentes.items.length === 1时,调用onChange。所以首先要确保Apollo的MockedProvider返回的mock数据符合这个结构。

修改你的mock数据示例:

// 定义符合条件的mock数据
const singleStickMock = {
  request: {
    query: ALL_STICKS,
    // 这里的variables要和组件传入Query的变量完全匹配
    variables: { 
      name: '',
      idProcess: 'II00000020000',
      isExceptional: false,
      codeClasse: null,
      codeSubject: null,
      codeCompetence: null
    }
  },
  result: {
    data: {
      varas_competentes: {
        items: [
          { id: 'test-stick-1', name: '测试法庭' } // 长度为1的数组,触发if条件
        ]
      }
    }
  }
};

第二步:修改测试用例,等待回调执行并验证行为

使用React Testing Library的waitFor(比wait(0)更可靠)来等待Query完成数据加载,触发onCompleted回调,然后断言你的onChange mock函数是否被正确调用。

修改后的完整测试代码:

import { render, waitFor, cleanup } from '@testing-library/react';
import { MockedProvider } from '@apollo/client/testing';
import SelectStick from './SelectStick';
import ALL_STICKS from './path-to-your-query/ALL_STICKS';

describe('SelectStick Component', () => {
  afterEach(cleanup);

  it('should call onChange when query returns exactly one stick', async () => {
    const testStick = { id: 'test-stick-1', name: '测试法庭' };
    const sticksMock = {
      request: {
        query: ALL_STICKS,
        variables: { 
          name: '',
          idProcess: 'II00000020000',
          isExceptional: false,
          codeClasse: null,
          codeSubject: null,
          codeCompetence: null
        }
      },
      result: {
        data: {
          varas_competentes: {
            items: [testStick]
          }
        }
      }
    };

    // 创建onChange的mock函数
    const onChangeMock = jest.fn();
    
    render(
      <MockedProvider mocks={[sticksMock]} addTypename={false}>
        <SelectStick 
          onChange={onChangeMock} 
          value={{}} 
          idProcess="II00000020000" 
        />
      </MockedProvider>
    );

    // 等待onCompleted触发,验证onChange是否被正确调用
    await waitFor(() => {
      expect(onChangeMock).toHaveBeenCalledWith(testStick);
    });
  });

  // 额外测试:当返回多个结果时,不触发onChange
  it('should NOT call onChange when query returns multiple sticks', async () => {
    const sticksMock = {
      request: {
        query: ALL_STICKS,
        variables: { 
          name: '',
          idProcess: 'II00000020000',
          isExceptional: false,
          codeClasse: null,
          codeSubject: null,
          codeCompetence: null
        }
      },
      result: {
        data: {
          varas_competentes: {
            items: [
              { id: 'stick-1', name: '法庭1' },
              { id: 'stick-2', name: '法庭2' }
            ]
          }
        }
      }
    };

    const onChangeMock = jest.fn();
    
    render(
      <MockedProvider mocks={[sticksMock]} addTypename={false}>
        <SelectStick 
          onChange={onChangeMock} 
          value={{}} 
          idProcess="II00000020000" 
        />
      </MockedProvider>
    );

    await waitFor(() => {
      expect(onChangeMock).not.toHaveBeenCalled();
    });
  });
});

关键注意点

  • 变量匹配:Mock的request.variables必须和组件传入Query的变量完全一致,否则MockedProvider不会返回你的mock数据。
  • waitFor的作用:它会自动等待异步操作完成(比如Query的网络请求模拟),直到断言条件成立,比固定时间的wait(0)更稳定。
  • 间接验证:我们不需要直接测试onCompleted函数本身,而是通过验证它触发的onChange行为,来间接确认if逻辑是否正确执行。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.08 23:42:31