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

React组件单元测试:条件式Apollo查询多场景测试方法

React组件单元测试:覆盖Apollo useQuery的三种场景

首先需要准备测试依赖:@testing-library/react、@apollo/client/testing,以及TypeScript相关测试工具(如果使用TS)。我们会用Apollo提供的测试工具mock useQuery,结合React测试库的断言方法覆盖三种场景。

1. 测试查询被跳过的场景

当skipCondition为'N'时,组件会跳过useQuery执行,需要验证此时查询并未被触发。

import { render } from '@testing-library/react';
import { useQuery } from '@apollo/client';
import MyComponent from './Component';

// Mock useQuery
jest.mock('@apollo/client', () => ({
  ...jest.requireActual('@apollo/client'),
  useQuery: jest.fn(),
}));

describe('MyComponent', () => {
  it('should skip the query when skipCondition is "N"', () => {
    // 重置mock,避免用例间污染
    (useQuery as jest.Mock).mockReset();

    render(<MyComponent id="123" skipCondition="N" />);

    // 断言useQuery从未被调用
    expect(useQuery).not.toHaveBeenCalled();
  });
});

2. 测试查询被调用的场景

当skipCondition不为'N'(比如传'Y')时,组件会执行查询,需要验证查询被正确触发且传入了正确变量。

import { render } from '@testing-library/react';
import { useQuery } from '@apollo/client';
import MyComponent from './Component';
import { GET_LINK_BY_ID } from './your-queries-file';

jest.mock('@apollo/client', () => ({
  ...jest.requireActual('@apollo/client'),
  useQuery: jest.fn(),
}));

describe('MyComponent', () => {
  it('should execute the query when skipCondition is not "N"', () => {
    (useQuery as jest.Mock).mockReset();
    // mock useQuery返回基础结构,保证组件正常运行
    (useQuery as jest.Mock).mockReturnValue({ error: undefined, refetch: jest.fn() });

    const testId = '123';
    render(<MyComponent id={testId} skipCondition="Y" />);

    // 断言useQuery被调用,参数匹配预期
    expect(useQuery).toHaveBeenCalledWith(GET_LINK_BY_ID, {
      variables: { id: testId },
      skip: false,
      onCompleted: expect.any(Function),
    });
  });
});

3. 测试模板中显示链接的场景

当查询完成后onCompleted将displayLink设为true时,页面应渲染出Test link。需要mock查询成功的返回值,触发onCompleted,再断言链接存在。

import { render, screen } from '@testing-library/react';
import { useQuery } from '@apollo/client';
import MyComponent from './Component';

jest.mock('@apollo/client', () => ({
  ...jest.requireActual('@apollo/client'),
  useQuery: jest.fn(),
}));

describe('MyComponent', () => {
  it('should display the link when onCompleted sets displayLink to true', () => {
    (useQuery as jest.Mock).mockReset();
    
    // mock useQuery并主动触发onCompleted回调
    (useQuery as jest.Mock).mockImplementation((query, options) => {
      // 传入符合业务逻辑的mock数据,确保触发displayLink=true
      options.onCompleted({ link: { exists: true } });
      return { error: undefined, refetch: jest.fn() };
    });

    render(<MyComponent id="123" skipCondition="Y" />);

    // 断言链接被渲染
    expect(screen.getByText('Test link')).toBeInTheDocument();
  });
});

补充说明

  • 若需测试错误场景,可在mock useQuery时返回error对象,验证组件的错误处理逻辑(如果有)。
  • 每个测试用例前重置mock函数,避免不同用例间的状态污染。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 07:51:11