node.js - 在编写使用 supertest 的测试时访问 req.session 对象

标签 node.js express supertest

我刚开始使用 supertestnock在我的快速应用程序中为中间件编写单元测试。

我的路由器设置处理的所有请求首先检查 session 属性的存在(我正在使用快速 session )。

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 设置)=> 调用 protected /api/someendpoint端点为 accessToken曲奇饼。 => 调用 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

关于node.js - 在编写使用 supertest 的测试时访问 req.session 对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39118250/

相关文章:

javascript - 导出服务器进行集成测试时出现 React Jest 问题

node.js - Supertest/Jest 检查 header 是否存在

javascript - 找不到 Socket.io.js(node.js + express + socket.io)

node.js - req.session 没有存储数据

javascript - Express.js 从外部 API 检索信息并呈现到站点

node.js - Connect JS/Express JS url 处理程序的通用预处理程序?

javascript - Jest 全局设置导致测试通过/失败不一致

node.js - 我没有获得 Node.js 的库异步,我错在哪里?

javascript - 重新布线和导入其他模块

node.js - 如果 "posttest"脚本失败, yarn "test"脚本将不起作用