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

如何使用Jest模拟TypeScript类的Getter属性?

问题:Jest自动模拟TypeScript类的公共Getter属性失败

待测试代码

MyClass.ts

import Dependency from "./Dependency";

export default class MyClass {
    public constructor(private dependency: Dependency) {}

    public DoIt(): string {
        return this.dependency.MyProp;
    }
}

Dependency.ts

export default class Dependency {
    public get MyProp(): string {
        return "A string";
    }
}

现有测试代码(存在问题)

import MyClass from "./MyClass";
import Dependency from "./Dependency";

jest.mock("./Dependency"); // 使用自动模拟

it("测试DoIt方法返回模拟的MyProp值", () => {
    // 准备
    const dependency = new Dependency();
    const sut = new MyClass(dependency);
    // dependency.MyProp = "Another string"; // 错误:无法分配给只读属性“MyProp”
    jest.spyOn(dependency, "MyProp", "get").mockReturnValueOnce("Another string"); // 错误:MyProp属性不存在

    // 执行
    const retval = sut.DoIt();

    // 断言
    expect(retval).toStrictEqual("Another string");
});

问题说明:Jest自动模拟默认只会识别类的方法,不会处理getter属性,导致运行时MyProp值为undefined,既无法直接赋值修改,用jest.spyOn也会提示属性不存在。需要在保留自动模拟的前提下,正确模拟该公共getter属性。


解决方案

方法1:补充自动模拟的getter定义

在项目中创建__mocks__/Dependency.ts文件(Jest会自动识别该目录下的模拟文件,无需修改原测试的jest.mock调用):

const mockMyProp = jest.fn(() => "A string");

export default class Dependency {
    public get MyProp(): string {
        return mockMyProp();
    }
}

// 暴露mock函数,方便测试中修改返回值
export { mockMyProp };

然后修改测试代码:

import MyClass from "./MyClass";
import Dependency, { mockMyProp } from "./Dependency";

jest.mock("./Dependency");

it("测试DoIt方法返回模拟的MyProp值", () => {
    // 准备
    mockMyProp.mockReturnValueOnce("Another string");
    const dependency = new Dependency();
    const sut = new MyClass(dependency);

    // 执行
    const retval = sut.DoIt();

    // 断言
    expect(retval).toStrictEqual("Another string");
    expect(mockMyProp).toHaveBeenCalled();
});

方法2:用Object.defineProperty重写实例getter

无需额外创建mock文件,直接在测试中修改实例的getter:

import MyClass from "./MyClass";
import Dependency from "./Dependency";

jest.mock("./Dependency");

it("测试DoIt方法返回模拟的MyProp值", () => {
    // 准备
    const dependency = new Dependency();
    // 重写getter并设置可配置,允许后续修改
    Object.defineProperty(dependency, "MyProp", {
        get: jest.fn().mockReturnValue("Another string"),
        configurable: true
    });
    const sut = new MyClass(dependency);

    // 执行
    const retval = sut.DoIt();

    // 断言
    expect(retval).toStrictEqual("Another string");
});

方法3:类型断言配合jest.spyOn

通过类型断言告诉TypeScript自动模拟后的实例包含该getter属性,再使用jest.spyOn:

import MyClass from "./MyClass";
import Dependency from "./Dependency";

jest.mock("./Dependency");

it("测试DoIt方法返回模拟的MyProp值", () => {
    // 准备
    const dependency = new Dependency() as unknown as { MyProp: string };
    jest.spyOn(dependency, "MyProp", "get").mockReturnValue("Another string");
    const sut = new MyClass(dependency as Dependency);

    // 执行
    const retval = sut.DoIt();

    // 断言
    expect(retval).toStrictEqual("Another string");
});

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 00:10:37