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

