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

如何使用Sinon正确Mock ES6类?依赖注入场景测试方法

如何Mock依赖注入的B类来测试A类

嘿,你用依赖注入的方式简直太明智了——这恰恰让Mock变得超级简单!因为你不需要去Mock整个B模块,只需要在测试A的时候,传入一个模拟的B实例就行,完全能隔离真实B的逻辑,精准测试A的行为。我给你用最常用的测试工具举两个例子:

用Jest测试的示例

创建一个A.test.js文件,代码如下:

const A = require('./A');

describe('Class A', () => {
  describe('doSomething方法', () => {
    // 测试B.doOther成功时,A.doSomething的表现
    it('当B.doOther返回成功时,doSomething应该正常resolve', async () => {
      // 手动创建Mock的B对象,模拟doOther返回resolved的Promise
      const mockB = {
        doOther: jest.fn().mockResolvedValue()
      };

      const aInstance = new A(mockB);
      // 验证doSomething能正常resolve
      await expect(aInstance.doSomething(123)).resolves.not.toThrow();
      
      // 额外验证:B的doOther方法确实被调用了
      expect(mockB.doOther).toHaveBeenCalled();
    });

    // 测试B.doOther失败时,A.doSomething的表现
    it('当B.doOther返回失败时,doSomething应该reject对应错误', async () => {
      const testError = new Error('模拟B方法出错');
      // 模拟doOther返回rejected的Promise
      const mockB = {
        doOther: jest.fn().mockRejectedValue(testError)
      };

      const aInstance = new A(mockB);
      // 验证doSomething会抛出对应的错误
      await expect(aInstance.doSomething(123)).rejects.toThrow(testError);
      expect(mockB.doOther).toHaveBeenCalled();
    });
  });
});

用Sinon测试的示例

如果你习惯用Sinon,思路是一样的,只是语法稍有不同:

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

describe('Class A', () => {
  describe('doSomething', () => {
    it('B.doOther成功时,doSomething正常resolve', async () => {
      const mockB = {
        doOther: sinon.stub().resolves()
      };

      const aInstance = new A(mockB);
      await aInstance.doSomething(123);
      // 验证doOther被调用
      sinon.assert.called(mockB.doOther);
    });

    it('B.doOther失败时,doSomething抛出对应错误', async () => {
      const testError = new Error('模拟B方法出错');
      const mockB = {
        doOther: sinon.stub().rejects(testError)
      };

      const aInstance = new A(mockB);
      await expect(aInstance.doSomething(123)).rejects.toThrow(testError);
      sinon.assert.called(mockB.doOther);
    });
  });
});

核心思路总结

  • 因为你的A类是通过构造函数接收B实例的(依赖注入),所以测试时完全不需要碰真实的B模块,手动造一个拥有doOther方法的模拟对象就行。
  • 你可以自由控制模拟对象的doOther方法返回成功还是失败,以此覆盖A类的不同分支逻辑。
  • 还能验证模拟方法是否被正确调用,确保A类的逻辑流程符合预期。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 04:21:24