如何使用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
相关产品推荐
相关产品推荐

