Node.js 柴湾测试中的护照认证
这是我第一个使用passport的项目,我对Node一般来说是新手。在使用Chai运行集成测试时,我很难将端点识别为授权端点。终点是 受使用passport和jsonwebtoken库的令牌身份验证保护。以下是导入到测试的其他文件Node.js 柴湾测试中的护照认证,node.js,authentication,integration-testing,chai,passport.js,Node.js,Authentication,Integration Testing,Chai,Passport.js,这是我第一个使用passport的项目,我对Node一般来说是新手。在使用Chai运行集成测试时,我很难将端点识别为授权端点。终点是 受使用passport和jsonwebtoken库的令牌身份验证保护。以下是导入到测试的其他文件 const chai = require('chai'); const chaiHttp = require('chai-http'); const mongoose = require('mongoose'); const should = chai.should(
const chai = require('chai');
const chaiHttp = require('chai-http');
const mongoose = require('mongoose');
const should = chai.should();
const { Session } = require('../models/practiceSession' );
const {User} = require('../models/user');
const { app, runServer, closeServer } = require('../app');
const { TEST_DATABASE_URL } = require('../config/mainConfig');
const {secret} = require('../config/mainConfig');
const jwt = require('jsonwebtoken');
chai.use( chaiHttp );
这是终点测试
//test the session endpoints
it( 'should return a session with proper request', function(){
const user = new User({
name: 'random2',
email: 'random2@random.com',
password: 'Password2'
});
user.save( (err) => {
if (err){
console.log( err.message);
}
});
const token = jwt.sign({
id: user._id,
userName: user.name,
level: 0
}, secret, {
expiresIn: 60 * 60
});
console.log( "user id: ", user._id);
console.log( 'token is: ', token );
const practiceRequest = {
operation: "+",
number: "10", ///this will possible need to be sent as a number
min: "1",
max: "200"
};
return chai.request(app)
.post('/api/session')
.set('Authorization', 'Bearer ' + token)
.send( practiceRequest )
.then( (res) => {
res.should.have.status(201);
})
});
});
这两条console.log语句确认正在创建用户并具有_id属性,并且正在创建有效的令牌
已创建(已在上确认)
这是端点的代码
router.route("/session")
.post(passport.authenticate('jwt', { session: false }), jsonParser, ( req, res ) => {
console.log( req );
let practiceSession = [];
for ( let i = 0; i < req.body.number; i++ ){
let firstTerm = generateTerm( req.body.min, req.body.max );
let secondTerm = generateTerm( req.body.min, req.body.max );
const problem = {
operator: req.body.operation,
firstTerm,
secondTerm,
problem: `${ firstTerm } ${ req.body.operation } ${ secondTerm }`,
correctResponse: generateCorrectResponse( firstTerm, secondTerm, req.body.operation )
};
practiceSession.push( problem );
}
// save session into db sessions collection for use in the training-logic.js
Session
.create( {
userId: req.user._id,
problems: practiceSession
} )
.then(
session => res.status( 201 ).json( session) )
.catch( err => {
console.error( err );
res.status( 500 ).json( { message: 'Internal Server Error' } );
});
} );
它仍然被拒绝,因为未经授权
。从测试发送到会话终结点的请求中缺少某些内容。会话端点中的console.log(req)
确认,与测试中从承诺链发送的内容相比,它正在接收一个添加了大量信息的对象。我必须使用外部作用域中的token变量在chai.request(app)
命令之间传递值。这与工作应用程序中存在的数据流不同。我不知道如何测试这一点;我的理解是,到目前为止,我所尝试的并没有为端点提供足够的数据来验证请求
任何帮助都将不胜感激。谢谢你抽出时间 解决方案
接下来,一位朋友帮助我解决了这个问题,并给了我一个解决方案,当我遇到问题时,该解决方案会将附加信息传递回端点
构建令牌。最终的工作模型有一个beforeach()
函数,该函数向测试数据库添加一个虚拟用户,然后
将此用户分配给外部作用域中的testUser
变量,以便在以后的测试中可以访问该变量。在实际测试中
端点此testUser
变量映射到完整的用户架构,用于构建令牌和测试端点。它运行良好,因为端点具有所需的所有属性。这是代码
describe( 'End-point for practice session resources', function() {
let testUser;
let modelSession;
before( function() {
return runServer( TEST_DATABASE_URL );
});
beforeEach( function(done){
addUser()
.then( user => {
testUser = user;
done();
});
});
以及测试
it( 'should generate a session with the proper request (POST)', function(){
const token = jwt.sign({
id: testUser._id
}, secret, { expiresIn: 60 * 60 });
return chai.request( app )
.post( '/api/session' )
.set( 'Authorization', `Bearer ${ token }` )
.send( {
operation: "+",
number: "10",
min: "1",
max: "200"
})
.then( res => {
res.should.have.status(201);
} )
})
});
希望这能帮助其他人 解决方案
接下来,一位朋友帮助我解决了这个问题,并给了我一个解决方案,当我遇到问题时,该解决方案会将附加信息传递回端点
构建令牌。最终的工作模型有一个beforeach()
函数,该函数向测试数据库添加一个虚拟用户,然后
将此用户分配给外部作用域中的testUser
变量,以便在以后的测试中可以访问该变量。在实际测试中
端点此testUser
变量映射到完整的用户架构,用于构建令牌和测试端点。它运行良好,因为端点具有所需的所有属性。这是代码
describe( 'End-point for practice session resources', function() {
let testUser;
let modelSession;
before( function() {
return runServer( TEST_DATABASE_URL );
});
beforeEach( function(done){
addUser()
.then( user => {
testUser = user;
done();
});
});
以及测试
it( 'should generate a session with the proper request (POST)', function(){
const token = jwt.sign({
id: testUser._id
}, secret, { expiresIn: 60 * 60 });
return chai.request( app )
.post( '/api/session' )
.set( 'Authorization', `Bearer ${ token }` )
.send( {
operation: "+",
number: "10",
min: "1",
max: "200"
})
.then( res => {
res.should.have.status(201);
} )
})
});
希望这能帮助其他人 James,谢谢你的介绍,我从来没有在Node的服务器端使用过Chrome调试器。在应用程序的正常运行中,我在sessionRouter端点(如上)中设置了一个断点,并检查了请求对象。在标题中有一个用于
授权的属性:“持有者eyJhbGciOiJIUzI1NiIsIn…”
我的理解是,这就是测试中发送的内容。这个工具提供了额外的信息,但我认为它证实了我一直在做的事情。我仍然不知道为什么这个测试会因为“未经授权”而失败。再次感谢您的时间。听起来像是令牌头正在上升(这很好)。将问题缩小到JWT无效:)身份验证调用。James,感谢您的参考,我从未在节点的服务器端使用Chrome调试器。在应用程序的正常运行中,我在sessionRouter端点(如上)中设置了一个断点,并检查了请求对象。在标题中有一个用于授权的属性:“持有者eyJhbGciOiJIUzI1NiIsIn…”
我的理解是,这就是测试中发送的内容。这个工具提供了额外的信息,但我认为它证实了我一直在做的事情。我仍然不知道为什么这个测试会因为“未经授权”而失败。再次感谢您的时间。听起来像是令牌头正在上升(这很好)。把你的问题缩小到JWT无效:)想一想澄清一下,事实上,通过回顾你的代码,你的问题很明显,你的测试中有一个竞争条件。创建用户,然后继续发送请求,然后才能确保用户已保存。我写了一个库,我认为它真的可以帮助简化您的测试,看看,它是专门为解决这样的问题而设计的。如果你对此有任何疑问,请告诉我:)太棒了!谢谢你,詹姆斯!不用担心,在我以前的工作中,我们发现自己进行了大量的集成测试,需要大量的设置,尽管Mocha很棒,但很容易陷入回调地狱或被类似于hit的场景绊倒,它现在是自动化测试过程的一个组成部分,每天都要运行数千个测试。文档中有一些简单的例子,但如果你正在努力解决这个问题,我很乐意用一个要点来“流畅地”说明你问题中的代码。想一想澄清一下,事实上,通过回顾你的代码,很明显,你的问题是你在测试中遇到了竞争条件。创建用户,然后继续发送请求,然后才能确保用户已保存。我写了一个库,我认为它真的可以帮助简化您的测试,看看,它是专门为解决这样的问题而设计的。如果你对此有任何疑问,请告诉我:)太棒了!谢谢你,詹姆斯!不用担心,在我以前的工作中,我们发现自己进行了大量的集成测试,需要大量的设置,尽管Mocha很棒,但很容易陷入回调地狱或被类似于hit的场景绊倒,它现在是自动化测试过程的一个组成部分,用于运行数千个测试