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

求助:如何用Jest编写GraphQL Mutation的onSuccess回调单元测试

覆盖GraphQL Mutation onSuccess回调的单元测试用例

以下基于React Testing Library + Jest提供两种可行的测试方案,覆盖你的onSuccess逻辑:


方案1:直接Mock GraphQL Hook

适合快速测试hook逻辑,无需模拟真实网络请求:

1. 准备Mock

首先mock你的useCreateMutation hook,让它返回的mutate函数能主动触发传入的onSuccess回调:

import { render, screen, fireEvent } from '@testing-library/react';
import YourComponent from './YourComponent';
import { useCreateMutation } from './path-to-your-mutation-hook';

// Mock 目标hook
jest.mock('./path-to-your-mutation-hook', () => ({
  useCreateMutation: jest.fn((options) => ({
    mutate: jest.fn(() => {
      // 触发传入的onSuccess回调
      options.onSuccess?.();
      return Promise.resolve();
    }),
    isLoading: false,
    isSuccess: false,
  })),
}));

// Mock refetch函数
const mockRefetch = jest.fn();

2. 编写测试用例

假设你的组件接收refetch作为props(或从其他hook获取,可对应mock该hook):

test('refetch is called when mutation succeeds', () => {
  // 渲染组件并传入mock的refetch
  render(<YourComponent refetch={mockRefetch} />);

  // 触发创建按钮点击
  const createBtn = screen.getByRole('button', { name: /创建/i });
  fireEvent.click(createBtn);

  // 验证mutate被调用且参数正确
  const mutateFn = useCreateMutation.mock.results[0].value.mutate;
  expect(mutateFn).toHaveBeenCalledWith({
    createRequest: { userId: '12' },
  });

  // 核心验证:onSuccess触发了refetch
  expect(mockRefetch).toHaveBeenCalledTimes(1);
});

方案2:用MSW模拟真实GraphQL请求

适合更贴近真实场景的测试,模拟实际网络请求响应:

1. 配置MSW服务器

import { render, screen, fireEvent, waitFor } from '@testing-library/react';
import YourComponent from './YourComponent';
import { setupServer } from 'msw/node';
import { graphql } from 'msw';

// 创建Mock服务器,拦截CreateMutation请求并返回成功响应
const server = setupServer(
  graphql.mutation('CreateMutation', (req, res, ctx) => {
    return res(ctx.data({ createRequest: { id: '12' } }));
  })
);

// 测试前后启动/关闭服务器
beforeAll(() => server.listen());
afterEach(() => {
  server.resetHandlers();
  jest.clearAllMocks();
});
afterAll(() => server.close());

const mockRefetch = jest.fn();

2. 编写测试用例

test('refetch triggers after successful mutation', async () => {
  render(<YourComponent refetch={mockRefetch} />);
  
  const createBtn = screen.getByRole('button', { name: /创建/i });
  fireEvent.click(createBtn);

  // 等待异步请求完成,验证refetch被调用
  await waitFor(() => {
    expect(mockRefetch).toHaveBeenCalledTimes(1);
  });
});

关键注意事项

  • 如果refetch来自useQuery,需要同步mock该query hook,确保refetch是可追踪的mock函数
  • 异步场景下必须用waitFor或findBy*系列查询等待操作完成
  • 若使用Apollo Client的useMutation,mock方式类似,只需调整hook路径及返回结构

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 02:52:32