如何在Mocha / Chai API单元测试中模拟req.session

时间:2019-04-18 22:04:37

标签: node.js express mocha chai chai-http

使用Mocha / Chai进行REST API单元测试,我需要能够模拟req.session.someKey的一些端点。我该如何嘲笑req.session

我正在为使用ExpressSession的NodeJS Express应用程序编写REST API单元测试。其中一些端点需要使用存储在req.session.someKey中的数据,如果req.session.someKey未定义,则该端点设置为返回400,因此我需要能够对其进行模拟,以使测试成功完成

示例代码:

router.get('/api/fileSystems', utilities.apiAuth, (req, res) => {
  let customer = req.session.customer;
  let route = (customer === 'NONE') ? undefined : customer;

  if(route == undefined){
    res.status(400).send('Can't have customer of undefined');
  } else {
    let requestOptions = setRequestOptions(route);
    queryFileSystemInfo(requestOptions, (info) => {
      res.status(200).send(info);
    });

  }
});

我尝试过的事情:

describe('/GET /api/fileSystems', () => {
  it('It should return information about the filesystem for a customer'), (done) => {
    chai.request(server)
      .get('api/fileSystems')
      .set('customer', '146')
      .end((err, res) => {
        res.should.have.status(200);
        done();
      });
  });
});

我尝试使用.set()来设置req.session,但是我相信.set只是设置标头,因此除非丢失了某些内容,否则我不敢以这种方式进行更新。

3 个答案:

答案 0 :(得分:1)

在快速设置中,通常会像这样插入会话中间件

app.use(session(config))

相反,您可以将会话中间件放在方便访问的位置,并为其包装,如下所示:

app.set('sessionMiddleware') = session(config)
app.use((...args) => app.get('sessionMiddleware')(...args)

测试将需要访问express实例,您可以通过重构/app.js来导出函数来实现。

function app () {
  const app = express()
  // ... set up express
  return app
}

// run app if module called from cli like `node app.js`
if (require.main === module) instance = app()

module.exports = app

然后在您的测试中,您可以覆盖app.sessionMiddleware

describe('/GET /api/fileSystems', () => {
  it('It should return information about the filesystem for a customer'), (done) => {
    app.set('sessionMiddleware') = (req, res, next) => {
      req.session = mockSession // whatever you want here
      next()
    }
    chai.request(server)
      .get('api/fileSystems')
      .set('customer', '146')
      .end((err, res) => {
        res.should.have.status(200);
        done();
      });

    // then you can easily run assertions against your mock
    chai.assert.equal(mockSession.value, value)
  });
});

我在网上看到的其他选项涉及设置cookie以匹配存储在db中的会话,这种方法的问题在于,当db中的会话到期时,您最终会遇到问题,因此随着设备的陈旧,测试会随着时间而失败。通过上面概述的方法,您可以通过在测试中设置过期时间来解决该问题。

答案 1 :(得分:0)

mock-session非常有用,可以模拟您的会话对象

 let mockSession = require('mock-session');

 describe('/GET /api/fileSystems', () => {
  it('It should return information about the filesystem for a customer'), (done) => {
    let cookie = mockSession('my-session', 'my-secret', {"count":1});  // my-secret is you session secret key. 

    chai.request(server)
      .get('api/fileSystems')
      .set('cookie',[cookie])
      .end((err, res) => {
        res.should.have.status(200);
        done();
      });
  });
});

答案 2 :(得分:0)

对于这个项目,我最终不得不在我们的server.js文件中设置req.session.customer,该文件具有一个app.use()调用,该调用使用中间件功能来设置当前会话。我实际上找不到在测试时直接使req.session对象发生变化的程序包。