jest.spyOn无法监听同模块函数内部调用方法,不使用rewire如何解决?
失效原因
你当前的测试无法命中调用的核心是:doSomething 内部调用的是模块私有作用域下的doAnotherThing函数,而jest.spyOn只能替换导出对象module.exports上挂载的doAnotherThing属性,二者指向的是完全独立的两个函数引用,因此监听不到内部调用。
无需第三方工具的解决方案
方案1:修改模块内调用路径(改造成本最低,无副作用)
将doSomething内部的doAnotherThing()调用改为指向导出对象上的方法即可,生产逻辑完全不变,仅调整调用引用:
const doSomething = () => { const test = 1; // 改为调用导出对象上挂载的方法,和spy的监听对象对齐 module.exports.doAnotherThing(); return test + 1; }; const doAnotherThing = () => {}; module.exports = { doSomething, doAnotherThing };
修改后你原有的测试代码不需要做任何调整,即可正常监听到调用。
方案2:封装为类实现(适合逻辑相对复杂的模块)
如果不想在业务代码中直接引用module.exports,可以把相关逻辑封装为类,通过实例引用调用内部方法,spy时直接监听实例/原型上的方法即可:
修改后的模块代码:
class MyModule { doSomething() { const test = 1; this.doAnotherThing(); return test + 1; } doAnotherThing() {} } // 导出单例实例,也可以导出类本身,测试时初始化实例再spy module.exports = new MyModule();
对应测试代码:
const MyModule = require('./myModule'); describe('MyModule', () => { it('Should be able to spy another call', () => { const spy = jest.spyOn(MyModule, 'doAnotherThing'); MyModule.doSomething(); expect(spy).toHaveBeenCalledTimes(1); }); });
内容的提问来源于stack exchange,提问作者Iuri
相关产品推荐
相关产品推荐

