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

