Тестирование экспресс-маршрутов с заглушками Sinon
Я пытаюсь провести модульное тестирование экспресс-маршрутов, чтобы убедиться, что они вызывают правильные функции контроллера. На данный момент я не проверяю внутреннюю логику функций контроллера, только то, что маршруты отображаются на нужные функции. То, что у меня до сих пор работает отлично, пока я не представлю промежуточное программное обеспечение маршрутизатора, например, так:
'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 для проверки доступа к каждому маршруту. Если я удаляю это, мои тесты проходят, добавление промежуточного программного обеспечения приводит к их сбою. Мне, вероятно, нужно заглушить методы 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.
1 ответ
Используйте заглушки для обеспечения прямого или неопределенного ввода SUT с известными значениями.
Вы, вероятно, думаете о том, чтобы подтвердить факт, какая функция представления должна быть доступна при маршрутизации в некоторых условиях. В этом случае используйте заглушки для предоставления промежуточному программному обеспечению входных данных, которые влияют на их поведение (например, учетные данные пользователя, например, для аутентификации). Не заменяйте сами промежуточные программы заглушками, потому что такой тест не будет иметь значения, если заглушка полностью изменит поведение.