如何在Jest测试中Mock @InjectValue装饰器修饰的属性
解决方法
针对你的场景,由于TestClient的构造函数在实例化时就会读取this.valueA,必须在实例化前完成值的注入,以下是两种可行方案:
方案一:Mock @InjectValue 装饰器
如果@InjectValue来自依赖库或自定义工具,可以直接Mock这个装饰器,让它在类定义阶段就为valueA赋值:
// 假设@InjectValue来自你的注入模块,比如"src/inject-decorators" jest.mock("src/inject-decorators", () => ({ InjectValue: jest.fn((key: string) => { return (target: any, propertyKey: string) => { // 根据注入key匹配赋值 if (key === "VALUE_A") { target[propertyKey] = "https://mock-host.com"; } }; }) })); // 务必在Mock之后导入TestClient import { TestClient } from "./test-client"; it("Should instantiate the client with injected valueA", () => { const client = new TestClient("dummy-token"); expect(client).toBeInstanceOf(TestClient); // 验证注入值(因valueA是私有属性,需跳过TS类型检查) // @ts-ignore expect(client.valueA).toBe("https://mock-host.com"); });
方案二:实例化前通过Object.defineProperty设置属性
如果不想Mock装饰器,可直接在创建实例前修改类的原型属性默认值:
import { TestClient } from "./test-client"; it("Should instantiate the client with custom valueA", () => { // 给TestClient原型添加valueA属性并赋值 Object.defineProperty(TestClient.prototype, "valueA", { value: "https://mock-host.com", writable: true }); const client = new TestClient("dummy-token"); expect(client).toBeInstanceOf(TestClient); // @ts-ignore expect(client.valueA).toBe("https://mock-host.com"); });
注意事项
- 方案一更贴合真实注入逻辑,适合模拟完整流程的测试场景;
- 方案二更简洁,适合快速验证实例化逻辑,但跳过了装饰器的实际执行;
- 因
valueA是私有属性,TypeScript会报错,需用// @ts-ignore跳过检查,或用(client as any).valueA访问。
内容的提问来源于stack exchange,提问作者Guillermo
相关产品推荐
相关产品推荐

