如何在Jest中Mock被构造函数调用的JavaScript实例方法
在Jest中Mock构造函数内调用的实例方法
问题场景
你遇到的情况是这样的:有一个类的构造函数会直接调用实例方法,比如下面的代码(注:原代码构造函数中调用helper()会报错,实际需加this指向实例方法):
class Example { constructor() { // 其他逻辑 this.helper(); // 其他逻辑 } helper() { // 内部实现 } }
常规的Mock方式是实例化后再给方法赋值jest.fn(),但这时候构造函数已经执行完,helper早就被调用过了,根本捕获不到调用记录。你想要验证构造函数确实调用了helper,同时不想Mockhelper的内部逻辑,仅做调用验证——目的是优化测试结构,避免处理helper里无需测试的代码。
可行解决方案
方案1:提前Mock类的原型方法
类的实例方法本质挂载在原型上,所以可以在实例化之前,直接把原型上的helper替换成Mock函数:
// 先替换原型上的helper为Mock函数 Example.prototype.helper = jest.fn(); // 再实例化类 const example = new Example(); // 验证Mock函数被调用 expect(Example.prototype.helper).toHaveBeenCalled();
如果有多个测试用例,记得在每个用例结束后清除Mock调用记录,避免干扰其他测试:
afterEach(() => { jest.clearAllMocks(); });
方案2:用jest.spyOn监听并Mock原型方法
这种方式更灵活,还能在测试结束后恢复原方法的实现:
// 监听原型上的helper方法,替换成空的Mock实现 const helperSpy = jest.spyOn(Example.prototype, 'helper').mockImplementation(() => {}); // 实例化类 const example = new Example(); // 验证方法被调用 expect(helperSpy).toHaveBeenCalled(); // 测试完成后恢复原方法 helperSpy.mockRestore();
这个方案的好处是不会污染类的原型,测试结束后能还原成原来的helper方法,适合需要复用类的其他测试场景。
特殊情况说明
如果你的helper是箭头函数(比如helper = () => {}),那它是实例的自有属性,而非挂载在原型上,上面的方法就失效了。这种情况建议重构代码,把箭头函数改成普通的实例方法,或者把helper的逻辑抽离成独立函数再Mock。
内容的提问来源于stack exchange,提问作者Zack
相关产品推荐
相关产品推荐

