有没有办法直接访问req
中的supertest
对象,而/在测试请求后?我想测试我的passport
策略,因此我想查看req.user
,req.session
以及其他人。我知道我可以测试页面重定向或flash,因为这些是我的策略所做的,但是看看req
对象上是否还有用户似乎很有用。如果我这样做,我还可以检查一次有多少用户。
我将使用“local-signup”策略对用户进行签名,该策略由此定义:
'use strict';
// get passport & mongoose
var passport = require('passport');
var LocalStrategy = require('passport-local').Strategy;
var UserModel = require('mongoose').model('User');
module.exports = function() {
// signup function
passport.use('local-signup', new LocalStrategy({
passReqToCallback: true // pass the entire request to the callback
},
function(req, username, password, done) {
process.nextTick(function() {
// find a user with the same username
UserModel.findOne({username: username}, function(err, user) {
// if there is an error, log it then return it
if(err) {
console.log("Error finding a user in the database: " + err);
return done(err);
}
// if a user was already found
if(user) {
return done(null, false, "User already exists");
}
// if we get this far, create a new user from the request body
var newUser = new UserModel(req.body);
// save it and sign it in
newUser.save(function(err) {
if(err) {
console.log("Error during signup: " + err);
return done(err);
}
return done(null, newUser);
});
});
});
}
));
};
我使用此策略的一种方式是:
我的“本地”策略定义如下:
'use strict';
var passport = require('passport');
var LocalStrategy = require('passport-local').Strategy;
var UserModel = require('mongoose').model('User');
module.exports = function() {
// create our local passport strategy & use it
passport.use(new LocalStrategy({
// use the default names for the username & password fields
usernameField: 'username',
passwordField: 'password'
},
// main strategy function
function(username, password, done) {
// find user with given username
UserModel.findOne({
username: username
},
// with this username, do this
function(err, user) {
// if there's an error, log it then pass it along
if(err) {
console.log("Error during login: " + err);
return done(err);
}
// if the username and/or password is incorrect, return an error
// along with a message
if(!user || !user.authenticate(password)) {
return done(null, false, {
message: 'Invalid username and/or password'
});
}
// if everything is correct, return the user document from the database
return done(null, user);
});
}
));
};
我使用这两种策略,例如:
app.route(pageName).post(function(req, res, next) {
passport.authenticate(strategyName, function(err, user, info) {
if(err || !user) {
res.status(401).send(info);
}
else {
req.login(user, function(err) {
if(err) {
res.status(400).send(err);
}
else {
res.send(null);
}
});
}
})(req, res, next);
});
我试过
request = require('supertest');
this.authServer = require('../my-server');
request(this.authServer)
.put('/signup')
.set('Content-Type', 'application/json')
.set('Host', 'konneka.org')
.send(this.fullUser)
.end(function(req, res, done) {
console.log(res);
});
我在res
函数中记录的end()
对象,这里显示的时间太长,在其上定义了req
对象,但它似乎只有对象&在打开请求之前定义的函数。换句话说,它没有req.user
,req.session
或我想要的其他对象,因为在请求完成并且启动了新请求之后,它们被定义为。我注意到它也有状态代码,它们只在请求完成后定义,所以我必须遗漏一些东西。
在您测试的请求结束后,有没有办法访问req
对象?或者我是否完全以错误的方式解决这个问题?
答案 0 :(得分:9)
使用supertest
无法执行您想要的操作。
不确定这是否有帮助,但我会添加一些背景来澄清答案:
supertest
是superagent
(客户端)之上的包装器,其中包含一些基本挂钩到express
以启动HTTP侦听器。在引擎盖下,它与启动您的快速应用程序,等待它在端口上侦听,向该端口发出HTTP请求以及解析结果没有任何不同。事实上,这正是它所做的。
所以基本上supertest
只能访问您的客户端可以访问的内容(浏览器或某个API客户端)。换句话说,如果它不在HTTP响应主体中,您将无法访问它。 req.user
和req.sesssion
是服务器端状态变量(很可能)不在响应中(除非你做了一些奇怪的事情)。
如果您想要完全按照描述的方式进行测试,则必须使用一些替代的测试策略,而不是supertest
。
答案 1 :(得分:0)
当我认为我想要这样做时,我发现了这个问题,对我来说,检查请求创建的用户的状态而不是验证req对象的内容是很有效的。您可以访问完整的数据库,我假设您的用户以某种方式结束。