我正在尝试测试使用 express 和 passport.js 的 Nodejs 应用程序。
所以在我的主要
app.js
文件中,我需要这样的 passportConfig 文件:
const passport = require('passport');
const passportConfig = require('./routes/passport.js');
// Configure global passport object
passportConfig(passport);
这是我的自定义 passport.js 文件的样子:
// load all the things we need
const LocalStrategy = require('passport-local').Strategy;
const sha = require('sha256');
const sql = require('mssql');
const fs = require('fs');
const path = require('path');
const connection = require('../middleware/database');
// expose this function to our app using module.exports
module.exports = async function (passport) {
const pool = await connection;
.......
.......
如您所见,我正在获取从
app.js
传递到此模块的护照对象,并向其加载各种策略。在这个函数中我有:
passport.use('admin-login', new LocalStrategy(
{
// by default, local strategy uses username and password, we will override with email
usernameField: 'username',
passwordField: 'password',
passReqToCallback: true, // allows us to pass back the entire request to the callback
},
((req, name, password, done) => { // callback with name and password from our form
async function verifyAdminAuth() {
Everything is working node and express wise。 Express 使全球通行证成为对象,所有策略随处可用。
现在,用于管理员登录的我的登录路由文件
login.js
如下所示:
const passport = require('passport');
router.post('/login/admin', bouncer.block, passport.authenticate('admin-login', {
successRedirect: '/',
failureRedirect: '/failure',
}), (req, res) => {
});
正如您在上面看到的,我直接从 node_modules 库加载 passport.js,所以它不应该有我实现的自定义策略。然而,凭借 express 的魔力,由于 express 缓存了它加载的所有自定义策略的库,我添加的事件虽然在
app.js
文件中。
我可以使用我的浏览器向
/admin/login
发送带有用户名和密码参数的发布请求,一切正常。但是当使用 supertest 从玩笑中做同样的事情时,它会抛出一个错误:
POST /login/admin 500 28.396 ms - 7976 console.log
{ status: 500, message: 'Unknown authentication strategy "admin-login"',
这是我的测试文件的样子:
const request = require('supertest');
const { app } = require('../app');
/* eslint-env jest */
// Info on Mocking: https://jestjs.io/docs/en/mock-functions.html
describe('POST /postNewBook', () => {
test('should return status 200 ', async () => {
const agent = request.agent(app);
// This route requires an authenticated user. So lets create an authenticated agent
// we will just piggyback off of it and make further requests.
const res = await agent.post('/login/admin').send({ username: 'Admin', password: 'MyAdminPassword' });
// Before moving on lets check if agent is authenticated
console.log(res.body);
expect(res.status).toEqual(200);
});
我对
jest
和supertest
都很陌生。我的理解是 supertest 将加载 Nodejs 服务器,就像使用命令行自己运行节点服务器一样。我已经能够成功地进行其他简单的获取和发布路由测试。但是在测试经过身份验证的路由时,我似乎缺少一些东西。为什么 supertest
不承认已经添加了“管理员登录”身份验证策略。是的,它与login.js
不在同一个文件中,但如果它运行的一切都一样,为什么它会在这里失败?
你应该知道,
passport
策略,在你的测试上下文中不会自动可用,所以你需要从你的 passport
文件中导出 passport.js
并在你的测试中需要它
例如
const request = require('supertest');
const { app } = require('../app');
const passport = require('../routes/passport'); // import the passport object
describe('TEST`', () => {
beforeAll(() => {
passport(passport);
});
test('login test (should return status 200)', async () => {
const agent = request.agent(app);
const res = await agent.post('/login/admin').send({ username: 'admin', password: 'admin' });
expect(res.status).toEqual(200);
});
});
应该有用
错误信息“Unknown authentication strategy 'admin-login'”告诉你超测找不到admin-login认证策略。这是因为您正在从 node_modules 目录加载 Passport,该目录没有您的自定义策略。
试试这个,
const request = require('supertest');
const { app } = require('../app');
const agent = request.agent(app, {
passport: './routes/passport.js',
});
describe('POST /login/admin', () => {
test('should return status 200 ', async () => {
const res = await agent.post('/login/admin').send({ username: 'Admin', password: 'MyAdminPassword' });
expect(res.status).toEqual(200);
});
});
希望这有效!