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

Jest为何能监视部分类私有函数,却无法监视其他?

为什么Jest监视类的部分私有方法失败?

问题场景

我尝试测试一个包含私有方法的类,示例代码如下:

class MyClass {
  private toggleState(): void {
    this.myState = true;
  }

  private updateFile(filePath: string): void {
    someFunctionThatUpdatesFile()
  }

  private openFile(filePath: string): void {
    someFunctionThatOpensFile()
  }

  private getPath(file: string): string {
    return "/some/path/to/file"
  }
}

测试代码中:

test("my test", () => {
  const spyGetPath = jest.spyOn(MyClass.prototype as any, "getPath") // 正常工作
  const spyOpenFile = jest.spyOn(MyClass.prototype as any, "openFile") // 正常工作

  const spyToggleState = jest.spyOn(MyClass.prototype as any, "toggleState") // 提示无法监视,因不是函数
  const spyUpdateFile = jest.spyOn(MyClass.prototype as any, "updateFile") // 提示无法监视,因不是函数
});

前两个spy能正常工作,后两个却提示无法监视(不是函数),这是为什么?

问题原因

核心在于TypeScript私有方法的编译输出差异:

  • 引用了this的私有方法(比如toggleState里访问this.myState),TypeScript会将其编译为实例方法——这类方法存储在类的实例自身,而非原型对象上。
  • 没有引用this的私有方法(比如getPath、openFile),会被编译为原型方法,因此能通过MyClass.prototype直接访问到。

Jest的spyOn需要目标是原型上可访问的函数,对于存储在实例上的方法,直接监视原型自然找不到对应的函数,所以会报错。

解决方法

要监视这类引用了this的私有方法,需要先创建类的实例,再监视实例上的方法:

test("my test", () => {
  const instance = new MyClass() as any;
  // 监视实例上的私有方法
  const spyToggleState = jest.spyOn(instance, "toggleState");
  const spyUpdateFile = jest.spyOn(instance, "updateFile");
  
  // 原有原型方法的监视保持不变
  const spyGetPath = jest.spyOn(MyClass.prototype as any, "getPath");
  const spyOpenFile = jest.spyOn(MyClass.prototype as any, "openFile");
});

另外需要注意:直接测试私有方法属于不推荐的做法,私有方法是类的内部实现细节,更合理的方式是通过测试类的公共方法来间接验证私有方法的行为,避免因内部实现变动导致测试失效。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.24 08:12:15