Mocha / Sinon 单元测试 JS Class 和实例问题
Mocha / Sinon Unit test JS Class and Instance issue
我正在尝试对某些 express 中间件进行单元测试,这些中间件依赖于我制作的某些 classes。
Middleware.js
const MyClass = require('../../lib/MyClass');
const myClassInstance = new MyClass();
function someMiddleware(req, res) {
myClassInstance.get().then(function(resp) {
res.render('somefile.html');
});
};
Test.js
const MyClass = require('../../lib/MyClass');
const sinon = require('sinon');
const chai = require('chai');
const expect = chai.expect;
// File we are testing
const someMiddleware = require('path/to/middleware');
MyClassMock = sinon.spy(function() {
return sinon.createStubInstance(MyClassMock);
});
describe('My Middleware', function() {
let renderSpy, classStub;
let res = {
render: function() {}
}
beforeEach(function() {
renderSpy = sinon.stub(res, 'render');
})
afterEach(function() {
renderSpy.restore();
})
it('should call render function', function() {
someMiddleware.someMiddleware(req, res);
expect(renderSpy.calledOnce);
});
});
我已经尝试了很多东西,但是我似乎无法真正模拟这个 class 并模拟创建的实例!当它 运行 时,它将尝试 运行 实际的 class 及其内部的相关依赖项。
大家好!
您的意图: replace/stub 您的中间件的依赖项。
您的问题:从您模块的外部这是不可能的。您不知何故需要 "intercept" 将使用哪个代码。
有两个选项,我在其他地方详细写过这两个选项(, , 3),所以我在这里做简写:
手动依赖注入
在您的中间件模块中,提供一个仅在测试中调用的 __setMyClassInstance(stubbedInstance)
方法。
- Pro:非常简单,不需要框架
- 缺点:test-only 打开模块的代码
Link接缝
这是关于用 returns 您喜欢的对象的另一个模块加载器替换您代码中的 require()
调用。在您的测试代码中:
const myMiddleware = proxyquire('../../src/middleware', { '../../lib/MyClass': myStubbedInstance })
- Pro:实现与DI相同,但无需修改模块中的代码
- 缺点:不清楚发生了什么,需要学习新的依赖项
如果您在看完这些非常简短的解释后仍感到困惑,我建议您查看我提供的 long-form 解释链接和 Link Seam 库教程的链接,例如 proxyquire
和 rewire
.
我正在尝试对某些 express 中间件进行单元测试,这些中间件依赖于我制作的某些 classes。
Middleware.js
const MyClass = require('../../lib/MyClass');
const myClassInstance = new MyClass();
function someMiddleware(req, res) {
myClassInstance.get().then(function(resp) {
res.render('somefile.html');
});
};
Test.js
const MyClass = require('../../lib/MyClass');
const sinon = require('sinon');
const chai = require('chai');
const expect = chai.expect;
// File we are testing
const someMiddleware = require('path/to/middleware');
MyClassMock = sinon.spy(function() {
return sinon.createStubInstance(MyClassMock);
});
describe('My Middleware', function() {
let renderSpy, classStub;
let res = {
render: function() {}
}
beforeEach(function() {
renderSpy = sinon.stub(res, 'render');
})
afterEach(function() {
renderSpy.restore();
})
it('should call render function', function() {
someMiddleware.someMiddleware(req, res);
expect(renderSpy.calledOnce);
});
});
我已经尝试了很多东西,但是我似乎无法真正模拟这个 class 并模拟创建的实例!当它 运行 时,它将尝试 运行 实际的 class 及其内部的相关依赖项。
大家好!
您的意图: replace/stub 您的中间件的依赖项。
您的问题:从您模块的外部这是不可能的。您不知何故需要 "intercept" 将使用哪个代码。
有两个选项,我在其他地方详细写过这两个选项(
手动依赖注入
在您的中间件模块中,提供一个仅在测试中调用的 __setMyClassInstance(stubbedInstance)
方法。
- Pro:非常简单,不需要框架
- 缺点:test-only 打开模块的代码
Link接缝
这是关于用 returns 您喜欢的对象的另一个模块加载器替换您代码中的 require()
调用。在您的测试代码中:
const myMiddleware = proxyquire('../../src/middleware', { '../../lib/MyClass': myStubbedInstance })
- Pro:实现与DI相同,但无需修改模块中的代码
- 缺点:不清楚发生了什么,需要学习新的依赖项
如果您在看完这些非常简短的解释后仍感到困惑,我建议您查看我提供的 long-form 解释链接和 Link Seam 库教程的链接,例如 proxyquire
和 rewire
.