javascript - 单元测试依赖注入
问题描述
我想在一个类中模拟依赖项,但我找不到正确的方法来实现这一点。使用 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
-----------|---------|----------|---------|---------|-------------------
推荐阅读
- angular - ngx-socket-io fromEvent 不能以角度工作
- javascript - “针对不同的模式版本编译”错误
- linux - 如何删除apache默认页面
- javascript - 跨域请求被阻止:同源策略不允许在 `localhost:...` 读取远程资源 - ExpressJS 和 npm Cors
- postgresql - Pg admin 4:MAC OS 上用户“postgres”的身份验证失败
- javascript - 未捕获的 TypeError:this.testFunction 不是函数
- r - 从工作区文件恢复以前的 R 代码
- c++ - 我应该使用 2 个 VBO 进行实例化吗?
- mathjax - 如何使用 Arithmatex 和 MathJax 获取 MkDocs 以将 \\[ ... \\] 识别为显示数学分隔符?
- python - 为什么单击功能在页面上不起作用,但在控制台上起作用?