使用Jest手动模拟导入的常量失效,请求技术帮助
解决Jest手动模拟常量失效的问题
问题根源
你的模拟失效主要有两个核心原因:
- 模块导入时机错误:
jest.mock必须在被依赖模块(此处为Age)导入前执行——Jest的模块拦截机制是在模块加载阶段生效的。你在beforeAll中调用jest.mock,但顶部已经提前导入了Age,此时原constants模块已完成加载,模拟无法覆盖原有值。 jest.mock返回值误用:jest.mock的返回值并非可用于mockRestore的mock对象,手动模拟的模块不需要通过该方法恢复。
解决方案1:提前调用jest.mock(推荐)
将jest.mock放在测试文件最顶部,确保在导入Age之前执行,Jest会优先加载你在src/__mocks__/constants.ts中定义的手动模拟:
// __tests__/src/age.test.ts // 先执行模拟,再导入依赖模块 jest.mock("../../src/constants"); import { Age } from "../../src/age"; describe("Test Age", () => { let age: Age; beforeEach(() => { age = new Age(); }); it("status返回OLD当CURRENT_AGE大于50时", () => { expect(age.status()).toBe("OLD"); }); // 如需测试不同常量值,可动态修改模拟 it("status返回YOUNG当CURRENT_AGE小于50时", () => { jest.mocked(import("../../src/constants")).CURRENT_AGE = 40; expect(age.status()).toBe("YOUNG"); }); });
解决方案2:动态模拟(适合测试中切换常量值的场景)
如果需要在测试过程中动态切换常量值,可使用jest.doMock配合require延迟模块加载:
// __tests__/src/age.test.ts describe("Test Age", () => { let Age: typeof import("../../src/age").Age; let age: InstanceType<typeof Age>; beforeEach(() => { // 清除之前的模块缓存,避免相互影响 jest.resetModules(); }); it("status返回OLD当CURRENT_AGE大于50时", () => { jest.doMock("../../src/constants", () => ({ CURRENT_AGE: 100, })); // 延迟导入Age模块,确保模拟生效 Age = require("../../src/age").Age; age = new Age(); expect(age.status()).toBe("OLD"); }); it("status返回YOUNG当CURRENT_AGE小于50时", () => { jest.doMock("../../src/constants", () => ({ CURRENT_AGE: 40, })); Age = require("../../src/age").Age; age = new Age(); expect(age.status()).toBe("YOUNG"); }); });
注意事项
- 手动模拟文件
src/__mocks__/constants.ts的路径必须与原模块路径严格对应,Jest会自动识别__mocks__目录下的模拟文件。 - 使用TypeScript时,需确保安装
@types/jest,以获得jest.mocked方法的类型支持。
内容的提问来源于stack exchange,提问作者Alicha Dinich
相关产品推荐
相关产品推荐

