单元测试依赖注入
Unit testing dependency injections
我想在 class 中模拟依赖关系,但我找不到正确的方法来实现它。使用 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?
});
});
});
我尝试对此进行研究,但找不到可行的解决方案。任何见解都会非常有帮助!提前致谢,对于造成的任何麻烦,我们深表歉意!
你应该用 Link Seams.
消除依赖
例如
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');
});
});
单元测试结果:
66751571
✓ should pass (2326ms)
1 passing (2s)
-----------|---------|----------|---------|---------|-------------------
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s
-----------|---------|----------|---------|---------|-------------------
All files | 81.82 | 100 | 50 | 81.82 |
classA.js | 100 | 100 | 100 | 100 |
classB.js | 50 | 100 | 0 | 50 | 3
classC.js | 50 | 100 | 0 | 50 | 3
-----------|---------|----------|---------|---------|-------------------
我想在 class 中模拟依赖关系,但我找不到正确的方法来实现它。使用 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?
});
});
});
我尝试对此进行研究,但找不到可行的解决方案。任何见解都会非常有帮助!提前致谢,对于造成的任何麻烦,我们深表歉意!
你应该用 Link Seams.
消除依赖例如
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');
});
});
单元测试结果:
66751571
✓ should pass (2326ms)
1 passing (2s)
-----------|---------|----------|---------|---------|-------------------
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s
-----------|---------|----------|---------|---------|-------------------
All files | 81.82 | 100 | 50 | 81.82 |
classA.js | 100 | 100 | 100 | 100 |
classB.js | 50 | 100 | 0 | 50 | 3
classC.js | 50 | 100 | 0 | 50 | 3
-----------|---------|----------|---------|---------|-------------------