我无法用 chai 和 sinon 测试我的 sails.js 控制器
I'm not able to test my sails.js controller with chai and sinon
我有一个控制器 Acounts,方法是 sum,还有一个名为 validation[=39= 的服务文件] 与对象 register。这个对象有一个方法 validate 来验证提供的表单和 return 一个布尔值。
控制器
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);
},
测试
//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
注
我知道测试应该执行我们正在调用的代码,同时替换那段代码(控制器)中调用的外部函数,使其 return 无论我们设置什么。如果测试正在执行那段代码,为什么我不能访问在控制器中创建的任何变量?
我试过监视 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/Whosebug/60182912
问题是我创建的生命周期文件信任 sails 文档。该文档用于集成测试,因为它会在任何其他测试之前起航。这很慢,而单元测试应该很快。擦除该文件足以成功测试控制器。否则帆会以我什至不完全理解的方式搞乱测试。我想这是由于风帆使服务在全球范围内可用。因此,当我的控制器调用验证服务时,这个 return 是一些默认值,而不是存根所说的 return。
更新:
我设法使它工作。测试前升帆时,只需要被测试的控制器,服务和模型不应该。
我有一个控制器 Acounts,方法是 sum,还有一个名为 validation[=39= 的服务文件] 与对象 register。这个对象有一个方法 validate 来验证提供的表单和 return 一个布尔值。
控制器
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);
},
测试
//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
注
我知道测试应该执行我们正在调用的代码,同时替换那段代码(控制器)中调用的外部函数,使其 return 无论我们设置什么。如果测试正在执行那段代码,为什么我不能访问在控制器中创建的任何变量?
我试过监视 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/Whosebug/60182912
问题是我创建的生命周期文件信任 sails 文档。该文档用于集成测试,因为它会在任何其他测试之前起航。这很慢,而单元测试应该很快。擦除该文件足以成功测试控制器。否则帆会以我什至不完全理解的方式搞乱测试。我想这是由于风帆使服务在全球范围内可用。因此,当我的控制器调用验证服务时,这个 return 是一些默认值,而不是存根所说的 return。
更新:
我设法使它工作。测试前升帆时,只需要被测试的控制器,服务和模型不应该。