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

如何在Jest中mock外部库的类构造函数,解决实例创建测试失败问题

问题根因

  • jest.mock 不允许写在测试用例(test块)内部,Jest执行时会优先把模块顶层的jest.mock声明提升到所有import语句之前执行,写在test块内的mock不会生效,导致你引入的仍然是真实的external-library模块。
  • 你当前的mock实现没有指定构造函数返回值,默认返回的mock实例虽然可以通过toBeTruthy校验,但如果需要自定义返回对象可以补充mock逻辑。

修改后的测试代码

// jest.mock必须写在模块顶层,不能放在describe/test块内部
jest.mock('external-library', () => {
  return {
    ExternalObject: jest.fn().mockImplementation((setting1, setting2) => {
      // 这里可以自定义返回你需要的mock对象,也可以留空返回默认mock实例
      return {}
    })
  }
});

// 注意要在mock完成之后再导入MyClass,否则MyClass引入的还是真实的ExternalObject
import { MyClass } from './你的MyClass文件路径';
// 如有相关类型定义也在这里导入
import { ISettings, Settings } from './你的类型定义路径';
import { ExternalObject } from 'external-library';

describe("Create Instance", () => {  
  test("Allow creation of external instance", () => {
    const settings: ISettings = new Settings();
    jest.spyOn(settings, "getSetting")
      .mockImplementationOnce(() => 'abcd')
      .mockImplementationOnce(() => 'xyz')

    const myImpl = new MyClass();
    const inst = myImpl.createInstance(settings);
    
    // 基础校验实例存在
    expect(inst).toBeTruthy();
    // 可选扩展:校验ExternalObject构造函数被正确调用,传参符合预期
    expect(ExternalObject).toHaveBeenCalledTimes(1);
    expect(ExternalObject).toHaveBeenCalledWith('abcd', 'xyz');
  });
});

额外注意点

  • 导入测试目标类MyClass的语句必须写在jest.mock之后,否则MyClass在mock执行前就已经引入了真实的ExternalObject,导致mock不生效。
  • 如果需要在不同测试用例中给ExternalObject设置不同的mock实现,可以在test块内调用(ExternalObject as jest.Mock).mockImplementation(/* 自定义逻辑 */)覆盖原有实现。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.10 17:57:01