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

使用Vitest模拟graphql-request遇404错误,求解决方案

解决Vitest模拟graphql-request时仍发送真实请求的问题

核心问题

你的模拟代码逻辑框架没问题,但因模块模拟未正确覆盖真实导入或模拟时机滞后,导致代码依然实例化了真实的GraphQLClient发起请求,最终返回404错误。

修复步骤

1. 确保模拟优先执行

Vitest的vi.mock会自动提升到所有导入语句之前,但如果测试文件中存在提前导入目标模块(比如TropicalWorld客户端)的情况,会导致模拟失效。必须保证先调用vi.mock,再导入被测试模块:

// 先执行模拟
vi.mock('graphql-request', () => ({
  GraphQLClient: class {
    request = vi.fn();
  },
  gql: (text) => text,
}));

// 再导入被测试的客户端模块
import { TropicalWorldClient } from './tropical-world-client';

2. 为request方法注入模拟逻辑

当前模拟仅创建了空的mock函数,需要在测试用例中为其指定返回值或抛出错误,同时要确保能获取到模拟的GraphQLClient实例:

测试正常路径

test('CheckIfFruitIsReallyTasty 返回预期结果', async () => {
  // 获取模拟的GraphQLClient类
  const { GraphQLClient } = await import('graphql-request');
  // 为request方法设置模拟返回值
  GraphQLClient.prototype.request.mockResolvedValue({
    fruit: {
      shop: { shopId: 'test-shop-123' }
    }
  });

  // 初始化客户端并调用目标方法
  const client = new TropicalWorldClient();
  const result = await client.CheckIfFruitIsReallyTasty('fruit-456');

  // 断言结果符合预期
  expect(result).toEqual(/* 你的业务预期结果 */);
  // 断言request方法被正确调用
  expect(GraphQLClient.prototype.request).toHaveBeenCalledWith(
    expect.any(String), // 匹配gql生成的查询文本
    { id: 'fruit-456' }
  );
});

测试错误路径

test('CheckIfFruitIsReallyTasty 正确处理请求错误', async () => {
  const { GraphQLClient } = await import('graphql-request');
  // 模拟请求抛出与实际一致的错误
  GraphQLClient.prototype.request.mockRejectedValue(new Error('ERROR status code: 404, status text: undefined'));

  const client = new TropicalWorldClient();
  await expect(client.CheckIfFruitIsReallyTasty('invalid-fruit-id')).rejects.toThrow('ERROR status code: 404, status text: undefined');
});

3. 排查模块导入一致性

确保TropicalWorld客户端中导入graphql-request的路径与测试中模拟的路径完全一致。如果客户端使用import { GraphQLClient } from 'graphql-request',则模拟写法无需调整;若使用别名或相对路径导入,需同步修改vi.mock的参数。

4. 私有方法测试的临时处理

如果CheckIfFruitIsReallyTasty是私有方法,可通过类的公共方法间接调用它,或在测试中临时通过client['CheckIfFruitIsReallyTasty']的方式访问(仅测试场景下使用)。

验证模拟是否生效

在测试用例中添加以下代码,确认是否使用了模拟的GraphQLClient:

const { GraphQLClient } = await import('graphql-request');
console.log(GraphQLClient.prototype.request); // 输出应为MockFunction,而非真实的request方法

内容的提问来源于stack exchange,提问作者Katharina Schreiber

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 23:44:55