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
相关产品推荐
相关产品推荐

