Reputation: 21
Using Mocha/Chai for REST API unit testing, I need to be able to mock req.session.someKey
for a few of the end points. How can I go about mocking req.session
?
I'm working on writing REST API unit tests for a NodeJS Express app that utilizes express-session. Some of these endpoints require the use of data stored in req.session.someKey
, the endpoint is setup to return a 400 if req.session.someKey
is undefined so I need to be able to mock it in order for the test to complete successfully.
Example code:
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);
});
}
});
What I've tried:
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();
});
});
});
I attempted to use the .set()
in order to set req.session but I believe that .set just sets the headers so I don't believe that I can update it that way unless I'm missing something.
Upvotes: 2
Views: 4469
Reputation: 1828
In your express setup you usually plug in the session middleware like this
app.use(session(config))
instead you can put the session middleware in a handy accessible location, and make a wrapper for it, like this:
app.set('sessionMiddleware') = session(config)
app.use((...args) => app.get('sessionMiddleware')(...args)
Tests will need access to the express instance, you can do this by refactoring /app.js
to export a function.
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
Then in your test, you can overwrite 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)
});
});
The other options I've seen on the net involve setting a cookie to match a session which is stored in the db, the problem with that approach is that you end up running into problems when the session in the db expires, so tests fail over time as fixtures become stale. With the approach outlined above you can work around that by setting expiries in the test.
Upvotes: 2
Reputation: 21
For this project, I ended up having to set req.session.customer
in our server.js file that has an app.use()
call that uses a middleware function to set the current session. I was unable to actually find a package that directly mutates the req.session object at test time.
Upvotes: 0
Reputation: 2014
mock-session is pretty use full to mock your session object
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();
});
});
});
Upvotes: 1