单元测试依赖注入

时间:2021-03-22 18:06:52

标签: javascript unit-testing mocking sinon sinon-chai

我想模拟一个类中的依赖项,但我找不到正确的方法来实现它。使用 sinon 进行单元测试。例如:

const { classB } = require("./classes/classB");
const { classC } = require("./classes/classC");
const sinon = require("sinon");

class classA {
    constructor() {
        this.classB = new classB();
        this.classC = new classC();
    }
 
    doSomething() {
        const data = this.classB.getInfo();
        const processed = processInfo(data);
        this.classC.processedData(processed);
        
    }
    
    processInfo(data) {
        // doesSomeProcessing
    }
}

module.exports = {
    classA
};

describe("classA", () => {
    describe("when instantiated", () => {
        it("calls classB's getInfo once, classC's processedData data once.", () => {
            sinon.stub(classB);
            let clsA = new classA();
            sinon.assert.calledOnce(classB.getInfo);
            sinon.assert.calledOnce(classC.processedData);
            // Also can we do something like this?
            // when classB.getinfo.then(provideMockData) 
            // so that we can mock the calls being made to avoid actual calls?
        });
    });
});

我尝试对此进行研究,但找不到可行的解决方案。任何见解都会非常有帮助!提前致谢并为给您带来的任何麻烦深表歉意!

1 个答案:

答案 0 :(得分:0)

您应该使用 Link Seams 排除依赖项。

例如

calc()

classA.js

const { ClassB } = require('./classB'); const { ClassC } = require('./classC'); class ClassA { constructor() { this.classB = new ClassB(); this.classC = new ClassC(); } doSomething() { const data = this.classB.getInfo(); this.classC.processedData(data); } } module.exports = { ClassA };

classB.js

class ClassB { getInfo() { return 'real data'; } } module.exports = { ClassB };

classC.js

class ClassC { processedData(data) { return 'real process data'; } } module.exports = { ClassC };

classA.test.js

单元测试结果:

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

describe('66751571', () => {
  it('should pass', () => {
    const classBInstanceStub = {
      getInfo: sinon.stub().returns('teresa teng'),
    };
    const classCInstanceStub = {
      processedData: sinon.stub(),
    };
    const ClassBStub = sinon.stub().returns(classBInstanceStub);
    const ClassCStub = sinon.stub().returns(classCInstanceStub);
    const { ClassA } = proxyquire('./classA', {
      './classB': { ClassB: ClassBStub },
      './classC': { ClassC: ClassCStub },
    });
    const clsA = new ClassA();
    clsA.doSomething();
    sinon.assert.calledOnce(classBInstanceStub.getInfo);
    sinon.assert.calledWithExactly(classCInstanceStub.processedData, 'teresa teng');
  });
});