我有一个使用方法sum的控制器Acounts和一个名为validation的服务文件以及一个对象register。该对象具有方法validate,该方法将验证提供的表单并返回布尔值。
Controller
sum: function(req, res) {
//validate form with a validation service function
const validator = new validation.register();
let check = validator.validate(req.body.form);
let count = 0;
if (check) {
count += 1;
} else {
count -= 1;
}
res.send(count);
},
test
//imports
const chai = require("chai");
const expect = chai.expect;
const sinon = require("sinon");
const util = require('util'); // to print complex objects
const acountsC = require("../../../api/controllers/AcountsController.js");
describe("AcountsController", function() {
describe("sum", function() {
let req = {
body: {
form: {}
}
}
let res = {
send: sinon.spy()
}
let validation = {
register: {
validate: function() {}
}
}
let stub_validate = sinon.stub(validation.register, "validate").returns(true);
it("count should be 1 when validation is true", function() {
acountsC.sum(req, res);
expect(count).to.equal(1);
});
});
});
测试日志
AcountsController
sum
1) count should be 1 when validation is true
0 passing (5s)
1 failing
1) AcountsController
sum
count should be 1 when validation is true:
ReferenceError: count is not defined
note
我知道测试应该执行我们正在调用的代码,同时替换该代码(控制器)中调用的外部函数,使其返回我们设置的任何内容。如果测试正在执行那段代码,为什么我不能访问控制器中创建的任何变量?
我已经尝试通过监视res.send(),并检查它是否以1调用。我没有成功。我到处搜索了如何对变量执行断言,但是什么也没找到。 :(
希望您能提供帮助
这是单元测试解决方案:
accountController.js
:
const validation = require('./validation');
class AccountController {
sum(req, res) {
const validator = new validation.register();
const check = validator.validate(req.body.form);
let count = 0;
if (check) {
count += 1;
} else {
count -= 1;
}
res.send(count);
}
}
module.exports = AccountController;
validation.js
:
class Register {
validate() {}
}
module.exports = {
register: Register,
};
accountController.test.js
:
const AccountController = require('./accountController');
const sinon = require('sinon');
const validation = require('./validation');
describe('60182912', () => {
afterEach(() => {
sinon.restore();
});
describe('#sum', () => {
it('should increase count and send', () => {
const registerInstanceStub = {
validate: sinon.stub().returns(true),
};
const registerStub = sinon.stub(validation, 'register').callsFake(() => registerInstanceStub);
const accountController = new AccountController();
const mRes = { send: sinon.stub() };
const mReq = { body: { form: {} } };
accountController.sum(mReq, mRes);
sinon.assert.calledWithExactly(mRes.send, 1);
sinon.assert.calledOnce(registerStub);
sinon.assert.calledWithExactly(registerInstanceStub.validate, {});
});
it('should decrease count and send', () => {
const registerInstanceStub = {
validate: sinon.stub().returns(false),
};
const registerStub = sinon.stub(validation, 'register').callsFake(() => registerInstanceStub);
const accountController = new AccountController();
const mRes = { send: sinon.stub() };
const mReq = { body: { form: {} } };
accountController.sum(mReq, mRes);
sinon.assert.calledWithExactly(mRes.send, -1);
sinon.assert.calledOnce(registerStub);
sinon.assert.calledWithExactly(registerInstanceStub.validate, {});
});
});
});
带有覆盖率报告的单元测试结果:
60182912
#sum
✓ should increase count and send
✓ should decrease count and send
2 passing (10ms)
----------------------|---------|----------|---------|---------|-------------------
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s
----------------------|---------|----------|---------|---------|-------------------
All files | 100 | 100 | 50 | 100 |
accountController.js | 100 | 100 | 100 | 100 |
validation.js | 100 | 100 | 0 | 100 |
----------------------|---------|----------|---------|---------|-------------------
源代码:https://github.com/mrdulin/expressjs-research/tree/master/src/stackoverflow/60182912
问题是我创建的生命周期文件信任Sails文档。该文档适用于集成测试,因为它可以在进行任何其他测试之前将帆抬起。这很慢,而单元测试应该很快。删除该文件足以成功测试控制器。否则,帆以一种我什至不完全理解的方式弄乱了测试。我想这是由于帆使服务在全球范围内可用。因此,当我的控制器要求验证服务时,该控制器将返回一些默认值,而不是存根表示应返回的值。
UPDATE:我设法使它起作用。在测试前举起帆时,仅需要测试的控制器,而无需服务和模型。