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

