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

使用Jest模拟第三方库仍调用真实内部实现的问题排查

问题原因及解决方案

问题原因

  1. Jest Mock 时机错误:jest.mock 被放在 beforeEach 函数内,而 Jest 的模块 mocking 机制是在模块加载阶段生效的。业务代码在测试代码执行前就已经导入了真实的 ChatSession,导致后续的 mock 无法覆盖真实实现。
  2. Mock 方式错误:你模拟的 ChatSession 是一个普通对象,而非可实例化的类(构造函数)。当执行 new ChatSession('', '') 时,实际调用的仍是原库中的真实构造函数,最终触发了真实的 sendMessage 方法,进而调用 fetch 导致报错。

解决方案

方案一:顶层配置正确的类 Mock

将 jest.mock 移到测试文件的最顶层,并正确模拟 ChatSession 构造函数及其方法:

// 放在测试文件最顶部,模块导入之前
jest.mock('@google/generative-ai', () => ({
  // 模拟构造函数,返回带有sendMessage方法的实例
  ChatSession: jest.fn().mockImplementation(() => ({
    sendMessage: jest.fn().mockResolvedValue({
      response: { text: jest.fn().mockResolvedValue('模拟返回内容') }
    })
  }))
}));

import sendMessage from '../../src/logic/actions/sendMessage';
import { ChatSession } from '@google/generative-ai';

let defaultParams: SendMessageParams;

beforeEach(() => {
  // 重置mock
  (ChatSession as jest.Mock).mockClear();
  const mockChatSession = new ChatSession('', '') as jest.Mocked<ChatSession>;
  defaultParams = {
    chatSession: mockChatSession,
    // ... 其他参数
  };
});

afterEach(() => {
  jest.clearAllMocks();
});

it('should send message', async () => {
  await sendMessage(defaultParams);
  // 验证sendMessage被调用
  expect(defaultParams.chatSession?.sendMessage).toHaveBeenCalled();
});

方案二:手动传入 Mock 实例(无需模块级 Mock)

直接创建一个符合 ChatSession 类型的 mock 对象,传入测试参数,避免依赖模块 mocking:

import sendMessage from '../../src/logic/actions/sendMessage';
import type { ChatSession } from '@google/generative-ai';

let defaultParams: SendMessageParams;

beforeEach(() => {
  // 手动创建mock实例
  const mockChatSession = {
    sendMessage: jest.fn().mockResolvedValue({
      response: { text: jest.fn().mockResolvedValue('模拟返回内容') }
    })
  } as unknown as ChatSession;

  defaultParams = {
    chatSession: mockChatSession,
    // ... 其他参数
  };
});

afterEach(() => {
  jest.clearAllMocks();
});

it('should send message', async () => {
  await sendMessage(defaultParams);
  expect(defaultParams.chatSession.sendMessage).toHaveBeenCalled();
});

补充:若需解决 fetch 问题(非必要,仅当未完全 mock 时)

如果因某些原因仍触发真实请求,可在 Jest 配置中启用 fetch:

  • 在 jest.config.js 中设置 testEnvironment: 'node'(Node 20+ 原生支持 fetch)
  • 或者安装 whatwg-fetch,并在测试入口导入:import 'whatwg-fetch';

内容的提问来源于stack exchange,提问作者Eray Erdin

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 21:12:54