如何在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
相关产品推荐
相关产品推荐

