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

如何在不修改解构导入写法的前提下用Sinon stub模块导出的独立函数

解决方案

可以实现,不需要修改现有业务代码的解构导入写法。

原写法失效原因

file.js中对fun的解构导入会在模块加载阶段执行,直接将code.js导出对象中fun的原始引用拷贝到file.js的内部作用域。你原有测试代码的执行顺序是先加载file.js完成拷贝,再对code.js的导出对象做stub,此时修改的只是导出对象的属性,不会影响file.js内部已经保存的原始函数引用,因此stub不生效。


实现方案1:调整加载顺序 + 清理模块缓存

仅需修改测试代码执行顺序,在加载file.js前先完成打桩,同时清理模块缓存避免缓存影响,示例代码如下:

const sinon = require('sinon');
const code = require('./code');

it('Should return Some Message', () => {
  // 先完成打桩
  const stubFun = sinon.stub(code, 'fun').returns(true);
  // 清理file模块的缓存,确保重新加载时拿到最新的stub引用
  delete require.cache[require.resolve('./file')];
  // 再加载file模块,此时解构拿到的就是已经打桩后的函数引用
  const abc = require('./file');

  // 执行测试逻辑
  abc.abc();

  // 可选:验证stub调用符合预期
  sinon.assert.calledOnce(stubFun);

  // 测试完成后恢复原函数,避免影响其他用例
  stubFun.restore();
});

如果有多个测试用例需要打桩,可以将清理缓存、加载模块的逻辑放到beforeEach钩子中统一处理。


实现方案2:搭配proxyquire做依赖替换

借助轻量依赖注入工具proxyquire,可以在不修改业务代码的前提下,直接替换file.js加载的依赖项,示例代码如下:

const sinon = require('sinon');
const proxyquire = require('proxyquire');

it('Should return Some Message', () => {
  // 构造stub
  const stubFun = sinon.stub().returns(true);
  // 加载file模块时,替换它依赖的./code模块的导出
  const abc = proxyquire('./file', {
    './code': {
      fun: stubFun
    }
  });

  // 执行测试逻辑
  abc.abc();

  // 验证stub调用符合预期
  sinon.assert.calledOnce(stubFun);
});

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 10:39:02