【发布时间】:2017-04-08 09:38:06
【问题描述】:
我正在尝试对 Express 路由进行单元测试,以验证它们调用了正确的控制器函数。此时,我不检查控制器功能的内部逻辑,只是检查路由映射到正确的功能。到目前为止,在我引入路由器中间件之前,我所拥有的一切都很好:
'use strict';
import express from 'express';
import config from './../../config/environments';
import SuperLogin from 'superlogin';
let controller = require('./subjects.controller');
let router = express.Router();
let superlogin = new SuperLogin(config);
router.get('/', superlogin.requireAuth, superlogin.requireAnyRole(['admin', 'specialist', 'nurse']), controller.index);
router.get('/:subjectId', superlogin.requireAuth, superlogin.requireAnyRole(['admin', 'specialist', 'nurse']), controller.show);
router.post('/', superlogin.requireAuth, superlogin.requireAnyRole(['admin', 'specialist', 'nurse']), controller.create);
router.put('/:subjectId', superlogin.requireAuth, superlogin.requireAnyRole(['admin', 'specialist', 'nurse']), controller.upsert);
router.patch('/:subjectId', superlogin.requireAuth, superlogin.requireAnyRole(['admin', 'specialist', 'nurse']), controller.patch);
router.delete('/:subjectId', superlogin.requireAuth, superlogin.requireAnyRole(['admin']), controller.destroy);
module.exports = router;
如您所见,我正在使用Superlogin 来验证对每条路线的访问权限。如果我删除这个我的测试通过,添加中间件会导致它们失败。我可能需要存根超级登录方法,但我不知道在哪里执行此操作。
我的测试如下
'use strict';
/* globals sinon, describe, expect, it */
let proxyquire = require('proxyquire').noPreserveCache();
let subjectCtrlStub = {
index: 'subjectCtrl.index',
show: 'subjectCtrl.show',
create: 'subjectCtrl.create',
upsert: 'subjectCtrl.upsert',
patch: 'subjectCtrl.patch',
destroy: 'subjectCtrl.destroy'
};
sinon.stub(superlogin, 'requireAuth', function(req, res, next) {
return next();
});
let routerStub = {
get: sinon.spy(),
put: sinon.spy(),
patch: sinon.spy(),
post: sinon.spy(),
delete: sinon.spy()
};
// require the index with our stubbed out modules
let subjectRoutes = proxyquire('./subjects.routes.js', {
express: {
Router() {
return routerStub;
}
},
'./subjects.controller': subjectCtrlStub
});
describe('Subject API Router:', function() {
it('should return an express router instance', function() {
subjectRoutes.should.equal(routerStub);
});
describe('GET /api/subjects', function() {
it('should route to subjects.controller.index', function() {
routerStub.get
.withArgs('/', 'subjectCtrl.index')
.should.have.been.calledOnce;
});
});
describe('GET /api/subjects/:subjectId', function() {
it('should route to subjects.controller.show', function() {
routerStub.get
.withArgs('/:subjectId', 'subjectCtrl.show')
.should.have.been.calledOnce;
});
});
describe('POST /api/subjects', function() {
it('should route to subjects.controller.create', function() {
routerStub.post
.withArgs('/', 'subjectCtrl.create')
.should.have.been.calledOnce;
});
});
describe('PUT /api/subjects/:subjectId', function() {
it('should route to subjects.controller.upsert', function() {
routerStub.put
.withArgs('/:subjectId', 'subjectCtrl.upsert')
.should.have.been.calledOnce;
});
});
describe('PATCH /api/subjects/:subjectId', function() {
it('should route to subjects.controller.patch', function() {
routerStub.patch
.withArgs('/:subjectId', 'subjectCtrl.patch')
.should.have.been.calledOnce;
});
});
describe('DELETE /api/subjects/:subjectId', function() {
it('should route to subjects.controller.destroy', function() {
routerStub.delete
.withArgs('/:subjectId', 'subjectCtrl.destroy')
.should.have.been.calledOnce;
});
});
});
我有一个 before 函数,它在所有这些测试之前运行,它使用一些具有不同角色的示例用户为数据库播种,并将授权令牌保存到全局变量中以在测试端点时使用,我只是不知道如何使用 routerStub 函数调用发送它们。
【问题讨论】:
标签: node.js express mocha.js sinon