user3703539
user3703539

Reputation: 437

Mocha/Sinon test mongoose inside express

I try to test this express route with mocha, supertest and sinon. Test can't pass promise, it stop after the first mongoose call in User.find callback function with a pending error message :

Error: timeout of 2000ms exceeded. Ensure the done() callback is being called in this test.

I call done() in the callback but nothing...

module.exports = function(app, User) {
app.route('/appointments')
.post(function(req,res){

    User.find({'department': req.body.department}, function(err, workers){
        return workers._id;
    }).then(function(allWorkers){

        var deferred = Q.defer();

        function sortWorkers(worker){
            return Appointments.find({worker: worker._id, start: req.body.date});
        };

        Q.all(_.map(allWorkers, sortWorkers)).done(function (val) {
            deferred.resolve(val);
        });

        return deferred.promise;

    }).then(function(workers){
        console.log(workers);
    })
    .catch(function(error) {
        console.log(error);
    })
    .done();
})
};

This is my begin test :

it("should save a user and not save the same", function(done){
    var appointments = new Appointments({title: 'okok',worker: '580359c86f7159e767db16a9',start:'2015-04-08T02:50:04.252Z' ,department: 95});

    console.log('appointments',appointments);
    request(app)
    .post("/appointments")
    .send(appointments)
    .expect(200)
    .end(function(err,res){
        console.log('ok',res);
        done();
    });
});

Upvotes: 0

Views: 172

Answers (3)

user3703539
user3703539

Reputation: 437

I found the solution : In my some of .then function have no condition and return nothing if workers array for example if empty that's why my test return timeout of 2000ms exceeded.

I add :

User.find({'department': req.body.department}, function(err, workers){
        if(workers.length == 0){
            res.status(500).json({ message: "Nobody in this department" });
        }
        return workers;
    })...

Upvotes: 0

Dmitriy Ievlev
Dmitriy Ievlev

Reputation: 331

Your should always return promise from your unit test. All you need is to add return before the request(app):

return  request(app)
        .post("/appointments")
        . . .
        .then(() => {
           expect(<your actual value>).to.equal(<expected value>)
        })

Upvotes: 0

Felipe Sabino
Felipe Sabino

Reputation: 18225

First, you don't need to call done at User.find promise

Also, your app.route('/appointments').post never returns anything as a response, try adding

res.end();

where you have console.log on the .then and .catch of your promise. You can use HTTP status code as well, like

...
}).then(function(workers){
   res.status(200).end();
})
.catch(function(error) {
   res.status(500).end();
})

This will ensure that .end(function(err,res){ ... }) is called on your test and the correct done function is called.

Upvotes: 0

Related Questions