[英]Accessing req.session object when writing tests that use supertest
我剛剛開始使用supertest
和nock
為我的快速應用程序中的中間件編寫單元測試。
我的路由器設置處理的所有請求首先檢查會話屬性的存在(我正在使用快速會話)。
app.use('/api', helpers.hasAccessToken, require('./routes.js'));
助手只是做:
module.exports.hasAccessToken = function(req, res, next) {
if(req.session.accessToken){
next();
} else {
res.status(401).send('LOGIN_SESSION_ENDED');
}
};
在我的測試規范中,我有:
var app = require('./index.js'),
request = require('supertest')(app),
expect = require('chai').expect,
nock = require('nock');
describe('GET requests', function(){
beforeEach(function(){
nock('https://somedomain:port')
.get('/someendpoint')
.reply(200, {foo:'bar'});
});
it('should return a 200 HTTP status code', function(done){
request
.get('/api/someendpoint')
.end(function(err, res){
expect(res.status).to.equal(200);
done();
});
});
});
而是返回狀態為 401 的此錯誤,我知道這是由於在運行測試之前沒有設置req.session.accessToken
屬性。
那么我怎樣才能在req
對象上做我喜歡的 session 對象呢?
謝謝
工作流程是:用戶登錄 => 在服務器端設置req.session.accessToken
=> 使用set-cookie
響應頭響應客戶端(cookie 由express-session
設置)=> 調用受保護的/api/someendpoint
端點accessToken
cookie。 => 調用hasAccessToken
中間件 => 其余代碼邏輯。
這是解決方案:
app.js
:
const express = require("express");
const session = require("express-session");
const helpers = require("./helpers");
const app = express();
app.set("trust proxy", 1);
app.use(
session({
secret: "keyboard cat",
resave: false,
saveUninitialized: true,
}),
);
app.post("/signin", (req, res) => {
req.session.accessToken = "123123";
console.info("signin success");
res.status(200).end();
});
app.use("/api", helpers.hasAccessToken, require("./routes"));
const server = app.listen(3000, () => {
console.info(`HTTP server is listening on http://localhost:${server.address().port}`);
});
module.exports = server;
helpers.js
:
module.exports.hasAccessToken = function(req, res, next) {
console.log("req.session.accessToken", req.session.accessToken);
if (req.session.accessToken) {
next();
} else {
res.status(401).send("LOGIN_SESSION_ENDED");
}
};
routes.js
:
const { Router } = require("express");
const router = Router();
router.get("/someendpoint", (req, res) => {
res.sendStatus(200);
});
module.exports = router;
app.test.js
:
const app = require("./app");
const request = require("supertest");
const expect = require("chai").expect;
describe("GET requests", function() {
const agent = request(app);
let cookies;
before((done) => {
agent.post("/signin").expect(200, (err, res) => {
if (err) return done(err);
expect(res.headers).to.have.property("set-cookie");
cookies = res.headers["set-cookie"].pop().split(";")[0];
done();
});
});
after((done) => {
app.close(done);
});
it("should return a 200 HTTP status code", function(done) {
console.log(cookies);
agent
.get("/api/someendpoint")
.set("Cookie", [cookies])
.end(function(err, res) {
if (err) return done(err);
expect(res.status).to.equal(200);
done();
});
});
});
帶有覆蓋率報告的集成測試結果:
HTTP server is listening on http://localhost:3000
GET requests
signin success
connect.sid=s%3Ahw94RpxRocC4hMTkCmMx4Ot85aGYG6s5.eE91ELDNjuQ1fWqEsRZdwtwKokLXR6%2Bao9NGdvl%2Bflc
req.session.accessToken 123123
✓ should return a 200 HTTP status code
1 passing (33ms)
-------------|----------|----------|----------|----------|-------------------|
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s |
-------------|----------|----------|----------|----------|-------------------|
All files | 93.33 | 50 | 100 | 97.67 | |
app.js | 100 | 100 | 100 | 100 | |
app.test.js | 90.48 | 50 | 100 | 100 | 11,27 |
helpers.js | 80 | 50 | 100 | 80 | 6 |
routes.js | 100 | 100 | 100 | 100 | |
-------------|----------|----------|----------|----------|-------------------|
源代碼: https : //github.com/mrdulin/mocha-chai-sinon-codelab/tree/master/src/stackoverflow/39118250
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.