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

使用Sinon Stub simple-git方法失败,改用proxyquire仍无效

问题:Sinon Stub simple-git 无效,改用proxyquire仍失败

我尝试用Sinon对simple-git库的方法做Stub来测试代码,但Stub完全被忽略。后来发现是因为测试方法里创建了新的simple-git实例,于是改用proxyquire,可问题还是没解决,哪里操作错了?

待测试代码

const git = require('simple-git');

module.exports.getGitPushCommandChildProcess = async (centralisedRepoFolderPath, branchName) => {
  logger.debug('#### executing getGitPushCommandChildProcess()');
  logger.debug(`  [arg1] - centralisedRepoFolderPath: ${centralisedRepoFolderPath}`);
  logger.debug(`  [arg2] - branchName: ${branchName}`);

  await git(centralisedRepoFolderPath)
    .push('origin', branchName);
};

原测试代码

it('merge request creation should succeed when running locally', async () => {
  // this will not get set when run locally
  process.env.PRIMARY_MR_ORIGINATOR_USERNAME = '';
  mockfs({
    'exchange-config': mockfs.load('test/unit/input-files/auto-merge-request/exchange-config')
  });
  sandbox.stub(git(), 'push').callsFake(() => Promise.resolve('pushed was called'));
  const { mrOpened, executionErrors } = await autoMergeRequestModule.openNewMergeRequest(
    apiObject,
    mockConfig,
    false
  );

  assert.strictEqual(executionErrors.toString(), '');
  assert.strictEqual(mrOpened, true);
});

更新后的proxyquire尝试

const gitStub = sinon.stub().callsFake(() => Promise.resolve());
proxyquire('../../../../src/publishing/auto-merge-request/lib/auto-merge-request-lib', {
  'simple-git': gitStub
});

问题分析与解决方案

原测试的核心问题

sandbox.stub(git(), 'push') 的问题在于:每次调用git()都会生成全新的simple-git实例,你Stub的只是这个临时实例的push方法,但业务代码会重新调用git(centralisedRepoFolderPath)生成另一个独立实例,Stub自然不会生效。

proxyquire尝试的错误

你的gitStub只模拟了simple-git函数本身,但simple-git的调用逻辑是先调用函数传入路径,返回实例对象,再调用该对象的push方法。现在的Stub只返回Promise,没有提供带push方法的实例对象,无法Stub到目标调用。

正确的proxyquire用法

需要让simple-git的Stub返回带有Stubbed push方法的对象,具体写法如下:

it('merge request creation should succeed when running locally', async () => {
  process.env.PRIMARY_MR_ORIGINATOR_USERNAME = '';
  mockfs({
    'exchange-config': mockfs.load('test/unit/input-files/auto-merge-request/exchange-config')
  });

  // 1. 创建实例Stub,包含push方法的Stub
  const gitInstanceStub = {
    push: sinon.stub().resolves() // 模拟push方法返回成功Promise
  };
  // 2. 让simple-git的Stub每次调用都返回这个实例Stub
  const gitStub = sinon.stub().returns(gitInstanceStub);

  // 3. 用proxyquire加载目标模块,替换simple-git为我们的Stub
  const autoMergeRequestModule = proxyquire('../../../../src/publishing/auto-merge-request/lib/auto-merge-request-lib', {
    'simple-git': gitStub
  });

  // 4. 执行测试逻辑
  const { mrOpened, executionErrors } = await autoMergeRequestModule.openNewMergeRequest(
    apiObject,
    mockConfig,
    false
  );

  // 5. 可选:验证push方法是否被正确调用
  sinon.assert.calledWith(gitInstanceStub.push, 'origin', /* 预期的分支名 */);

  assert.strictEqual(executionErrors.toString(), '');
  assert.strictEqual(mrOpened, true);
});

关键注意点

  • 必须使用proxyquire返回的模块对象(autoMergeRequestModule)执行测试,不能提前加载模块再替换,否则模块会使用原始的simple-git依赖。
  • 若需要模拟simple-git的链式调用(比如git().add().commit().push()),需要让实例Stub的每个方法都返回自身:
    const gitInstanceStub = {
      push: sinon.stub().resolves(),
      add: sinon.stub().returnsThis(),
      commit: sinon.stub().returnsThis()
    };
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 10:17:51