unit testing express route with async callback

2019-07-06 05:50发布

问题:

I'm writing an app in node.js using express.
I seperated the route definition from express so I will be able to unit test it without mocking out express.
What I did is:

file: usersRoutes.js

 var routes = {
  getAll: function(req,res) {
    var db = req.db; // req.db is initialized through a dedicated middleware function
    var usersCollection = db.get('users');
    usersCollection.find({},{limit:10},function(e,results){
      res.send(results);
    });
  }
};

module.exports = routes;

file: users.js

var express = require('express');
var router = express.Router();
var routes = require('./usersRoutes');

/* GET users listing. */
router.get('/', routes.getAll);

module.exports = router;

and finally in app.js:

var users = require('./routes/users/users.js');
app.use('/users', users);

Now, I want to write a unit test that checks that req.send is being called with the right parameter. I'm having trouble figuring out the correct way because the req.send is invoked asynchronously.
What is the correct way to unit test this function?

回答1:

if you are using mocha it provides the "done" function that you can inject into your callback and it will tell mocha that test is async and should wait until that function is called

it('should do something',function(done){
  reuest.send(function(){
     expect(true).toEqual(true);
     done()
  })
})

or something like that i don't remember is this is 100% the right syntax, but is pretty close this is good for callbacks but if you are using promises on the other hand you should check chai and mocha's promises assertions, are pretty cool



回答2:

I was looking for the answer to your question, was wondering if you ever managed to solve it. My work around was to have the route (middleware) return the 'promise' in the function. Then in my unit test you can do

return middleware(req, res).then(function () {
    expect(res.render).to.have.been.calledWith('whatever');
});