使用 Sinon-Chai 测试调用具有多个回调的 Node JS Express 路由中的单个回调
Testing with Sinon-Chai that an individual callback in a Node JS Express route with multiple callbacks is called
我对 Node 和 Sinon 比较陌生。这个应用程序是用 Express 制作的,我使用的是 Mocha、Chai 和 Sinon。使用 Sinon-Chai,我 POST 在 Express 中使用多个回调测试路由,但不知道如何检查第二次和后续回调。
我的index.js里面的路线是:
var controller = require('./example.controller');
var validator = require('./example.validator');
var router = express.Router();
router.post('/', validator.create, controller.create);
在我的validator.js中是检查提交参数的validator.create:
exports.create = function(req, res, next) {
var valid = true;
var errorMessages = [];
if (req.body.name) {
patt = /[^a-zA-Z0-9 !@#$%^&*()_+\-=\[\]{};':]/g;
if (patt.test(req.body.name)) {
valid = false;
errorMessages.push("Parameter is not alphanumeric");
}
}
if (valid == false) {
return res.status(400).json(errorMessages);
}
next();
}
在我的 controller.js 中是 controller.create,它在数据库中创建了一个条目:
exports.create = function(req, res) {
return Example.create(req.body)
.then(baseController.respondWithResult(res, 201))
.catch(baseController.handleError(res));
}
我的 Sinon-Chai 测试 index.spec.js:
var proxyquire = require('proxyquire').noPreserveCache();
var exampleCtrlStub = {
create: 'exampleCtrl.create',
};
var exampleValidatorStub = {
create: 'exampleValidator.create'
}
var routerStub = {
get: sinon.spy(),
put: sinon.spy(),
patch: sinon.spy(),
post: sinon.spy(),
delete: sinon.spy()
};
var exampleIndex = proxyquire('./index.js', {
express: {
Router() {
return routerStub;
}
},
'./example.controller': exampleCtrlStub,
'./example.validator': exampleValidatorStub
});
describe('POST /api/examples', function() {
it('should route to example.validator.create', function() {
routerStub.post
.withArgs('/', 'exampleValidator.create')
.should.have.been.calledOnce;
});
});
describe('POST /api/examples', function() {
it('should route to example.controller.create', function() {
routerStub.post
.withArgs('/', 'exampleCtrl.create')
.should.have.been.called;
});
});
虽然期望两个测试都通过,但第一个测试 (validator.create) 通过但第二个 (controller.create) 失败。我一直无法找到一种方法来测试是否调用了 controller.create。
在第二个测试中,我们不能使用 withArgs
跳过第一个验证器参数。测试失败,因为它正在寻找源代码中不存在的具有此签名的方法。
router.post('/', controller.create);
withArgs
始终从第一个参数开始,然后是第二个参数,依此类推。因此,解决方案是在测试中包含验证器
routerStub.post
.withArgs('/', 'exampleValidator.create', 'exampleCtrl.create')
.should.have.been.called;
参考:
希望对您有所帮助
我对 Node 和 Sinon 比较陌生。这个应用程序是用 Express 制作的,我使用的是 Mocha、Chai 和 Sinon。使用 Sinon-Chai,我 POST 在 Express 中使用多个回调测试路由,但不知道如何检查第二次和后续回调。
我的index.js里面的路线是:
var controller = require('./example.controller');
var validator = require('./example.validator');
var router = express.Router();
router.post('/', validator.create, controller.create);
在我的validator.js中是检查提交参数的validator.create:
exports.create = function(req, res, next) {
var valid = true;
var errorMessages = [];
if (req.body.name) {
patt = /[^a-zA-Z0-9 !@#$%^&*()_+\-=\[\]{};':]/g;
if (patt.test(req.body.name)) {
valid = false;
errorMessages.push("Parameter is not alphanumeric");
}
}
if (valid == false) {
return res.status(400).json(errorMessages);
}
next();
}
在我的 controller.js 中是 controller.create,它在数据库中创建了一个条目:
exports.create = function(req, res) {
return Example.create(req.body)
.then(baseController.respondWithResult(res, 201))
.catch(baseController.handleError(res));
}
我的 Sinon-Chai 测试 index.spec.js:
var proxyquire = require('proxyquire').noPreserveCache();
var exampleCtrlStub = {
create: 'exampleCtrl.create',
};
var exampleValidatorStub = {
create: 'exampleValidator.create'
}
var routerStub = {
get: sinon.spy(),
put: sinon.spy(),
patch: sinon.spy(),
post: sinon.spy(),
delete: sinon.spy()
};
var exampleIndex = proxyquire('./index.js', {
express: {
Router() {
return routerStub;
}
},
'./example.controller': exampleCtrlStub,
'./example.validator': exampleValidatorStub
});
describe('POST /api/examples', function() {
it('should route to example.validator.create', function() {
routerStub.post
.withArgs('/', 'exampleValidator.create')
.should.have.been.calledOnce;
});
});
describe('POST /api/examples', function() {
it('should route to example.controller.create', function() {
routerStub.post
.withArgs('/', 'exampleCtrl.create')
.should.have.been.called;
});
});
虽然期望两个测试都通过,但第一个测试 (validator.create) 通过但第二个 (controller.create) 失败。我一直无法找到一种方法来测试是否调用了 controller.create。
在第二个测试中,我们不能使用 withArgs
跳过第一个验证器参数。测试失败,因为它正在寻找源代码中不存在的具有此签名的方法。
router.post('/', controller.create);
withArgs
始终从第一个参数开始,然后是第二个参数,依此类推。因此,解决方案是在测试中包含验证器
routerStub.post
.withArgs('/', 'exampleValidator.create', 'exampleCtrl.create')
.should.have.been.called;
参考:
希望对您有所帮助