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

