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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 12:24:04