在使用Node.js(CompoundJS + PassportJS)构建的应用程序中,如何在锁定并需要登录的控制器上运行Mocha测试?我已经尝试过使用Superagent但是运气不好并且使用它需要运行服务器才能运行测试。我已经非常接近这个方法了,但是不想让服务器运行来运行单元测试。
我也尝试过使用护照并使用request.login
方法,最后我不断使用错误的passport.initialize()
中间件。
我正在努力坚持生成的CompoundJS测试,这些测试工作正常,直到涉及到身份验证。默认的CompoundJS测试运行init.js
文件,这样可以很好地处理身份验证并以某种方式使每个控制器测试可用:
require('should');
global.getApp = function(done) {
var app = require('compound').createServer()
app.renderedViews = [];
app.flashedMessages = {};
// Monkeypatch app#render so that it exposes the rendered view files
app._render = app.render;
app.render = function(viewName, opts, fn) {
app.renderedViews.push(viewName);
// Deep-copy flash messages
var flashes = opts.request.session.flash;
for (var type in flashes) {
app.flashedMessages[type] = [];
for (var i in flashes[type]) {
app.flashedMessages[type].push(flashes[type][i]);
}
}
return app._render.apply(this, arguments);
}
// Check whether a view has been rendered
app.didRender = function(viewRegex) {
var didRender = false;
app.renderedViews.forEach(function(renderedView) {
if (renderedView.match(viewRegex)) {
didRender = true;
}
});
return didRender;
}
// Check whether a flash has been called
app.didFlash = function(type) {
return !!(app.flashedMessages[type]);
}
return app;
};
控制器/ users_controller_test.js
var app,
compound,
request = require('supertest'),
sinon = require('sinon');
/**
* TODO: User CREATION and EDITs should be tested, with PASSPORT
* functionality.
*/
function UserStub() {
return {
displayName: '',
email: ''
};
}
describe('UserController', function() {
beforeEach(function(done) {
app = getApp();
compound = app.compound;
compound.on('ready', function() {
done();
});
});
/**
* GET /users
* Should render users/index.ejs
*/
it('should render "index" template on GET /users', function(done) {
request(app)
.get('/users')
.end(function(err, res) {
res.statusCode.should.equal(200);
app.didRender(/users\/index\.ejs$/i).should.be.true;
done();
});
});
/*
* GET /users/:id
* Should render users/index.ejs
*/
it('should access User#find and render "show" template on GET /users/:id',
function(done) {
var User = app.models.User;
// Mock User#find
User.find = sinon.spy(function(id, callback) {
callback(null, new User);
});
request(app)
.get('/users/42')
.end(function(err, res) {
res.statusCode.should.equal(200);
User.find.calledWith('42').should.be.true;
app.didRender(/users\/show\.ejs$/i).should.be.true;
done();
});
});
});
这些都因AssertionError: expected 403 to equal 200
或AssertionError: expected false to be true
答案 0 :(得分:0)
我在复合配置事件中使用了模拟passport.initialize,测试助手和侦听器的组合。
这提供了两件事:
beforeEach
代码。在test / init.js中我添加了方法来模拟passport.initialize **:
**发现于:
http://hackerpreneurialism.com/post/48344246498/node-js-testing-mocking-authenticated-passport-js
// Fake user login with passport.
app.mockPassportInitialize = function () {
var passport = require('passport');
passport.initialize = function () {
return function (req, res, next) {
passport = this;
passport._key = 'passport';
passport._userProperty = 'user';
passport.serializeUser = function(user, done) {
return done(null, user.id);
};
passport.deserializeUser = function(user, done) {
return done(null, user);
};
req._passport = {
instance: passport
};
req._passport.session = {
user: new app.models.User({ id: 1, name: 'Joe Rogan' })
};
return next();
};
};
};
然后我添加了一个要在每个控制器中调用的helpers.js文件:
module.exports = {
prepApp: function (done) {
var app = getApp();
compound = app.compound;
compound.on('configure', function () { app.mockPassportInitialize(); });
compound.on('ready', function () { done(); });
return app;
}
};
这将在每个控制器的beforeEach
中调用:
describe('UserController', function () {
beforeEach(function (done) {
app = require('../helpers.js').prepApp(done);
});
[...]
});