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

如何在React测试库中区分并Mock两个GraphQL Mutate查询?

区分并Mock多个GraphQL Mutate查询的测试方案

要在React测试中区分并依次Mock两个GraphQL Mutate查询,核心是利用Jest mock函数的参数判断能力,根据传入的mutation对象返回对应模拟数据,同时跟踪调用顺序。

1. 基于mutation对象匹配的Mock实现

替换你当前的graphql.mutate mock,改成根据传入的mutation参数分支返回数据:

// 确保已导入两个mutation常量到测试文件
import { closeMultipartUpload, fileUploadMutation } from './your-mutation-file-path';

graphql.mutate = jest.fn((options) => {
  // 判断当前调用的mutation类型
  if (options.mutation === fileUploadMutation) {
    return Promise.resolve({
      data: {
        createUploadUrl: {
          url: 'foo',
          documentID: '123'
        }
      }
    });
  } else if (options.mutation === closeMultipartUpload) {
    return Promise.resolve({
      data: {
        closeMultipartUpload: {
          versionID: 'v456'
        }
      }
    });
  }
  // 兜底处理未匹配的mutation
  return Promise.reject(new Error('Unknown mutation called'));
});

2. 验证调用顺序与参数

测试执行完成后,通过Jest mock函数的mock.calls属性验证调用顺序和参数是否符合预期:

// 验证两个mutation总共被调用2次
expect(graphql.mutate).toHaveBeenCalledTimes(2);

// 验证第一次调用的是createUploadUrl mutation
expect(graphql.mutate.mock.calls[0][0].mutation).toBe(fileUploadMutation);
// 可选:验证传入的变量参数
expect(graphql.mutate.mock.calls[0][0].variables).toEqual({
  directoryID: '预期的目录ID值',
  requesterID: '预期的请求者ID值'
});

// 验证第二次调用的是closeMultipartUpload mutation
expect(graphql.mutate.mock.calls[1][0].mutation).toBe(closeMultipartUpload);
// 可选:验证传入的变量参数
expect(graphql.mutate.mock.calls[1][0].variables).toEqual({
  directoryID: '预期的目录ID值',
  uploadID: '预期的上传ID值'
});

3. 处理mutation引用不一致的情况

如果因为模块导入方式等问题,导致测试文件中的mutation对象与业务代码中的不是同一个引用,可以通过解析mutation的名称字符串来匹配:

graphql.mutate = jest.fn((options) => {
  // 从mutation定义中提取名称
  const mutationName = options.mutation.definitions[0].name.value;
  
  if (mutationName === 'createUploadUrl') {
    return Promise.resolve({
      data: { createUploadUrl: { url: 'foo', documentID: '123' } }
    });
  } else if (mutationName === 'closeMultipartUpload') {
    return Promise.resolve({
      data: { closeMultipartUpload: { versionID: 'v456' } }
    });
  }
  return Promise.reject(new Error('Unknown mutation called'));
});

4. 针对useMutation钩子的Mock方式(若使用Apollo Client)

如果业务代码中用的是Apollo的useMutation钩子,可以用jest.spyOn来Mock:

import { useMutation } from '@apollo/client';

jest.spyOn(require('@apollo/client'), 'useMutation').mockImplementation((mutation) => {
  if (mutation === fileUploadMutation) {
    return [
      jest.fn(() => Promise.resolve({
        data: { createUploadUrl: { url: 'foo', documentID: '123' } }
      })),
      { loading: false }
    ];
  } else if (mutation === closeMultipartUpload) {
    return [
      jest.fn(() => Promise.resolve({
        data: { closeMultipartUpload: { versionID: 'v456' } }
      })),
      { loading: false }
    ];
  }
  return [jest.fn(), { loading: false }];
});

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 17:25:30