Tikkes Tikkes - 2 months ago 10
Javascript Question

Nested promises - Mocha - Exceeded timeout

I have got a test failing because of a timeout using Mocha.
I do call the "done()" function but it does not seem to work for some reason.

My test currently looks like this:

var express = require('express');
var expect = require('chai').expect;
var mocha = require('mocha');
var calendar = require('./../Server/calendarDatabase');

describe("Calendar", function () {
describe("Database", function () {
it("should get stuff from the database", function (done) {
return calendar.Connect()
.then(function () {
return calendar.getAll();
})
.then(function (returnValue) {
expect(returnValue.count).to.equal(5); //This should fail, my database records are 20+
done();
});
});
});
});


Where my
calendar.Connect()
and
calendar.getAll()
are both promises:

var express = require('express');
var sql = require('mssql');

var config = require('./../config');
var calendarDbConnection = {};

calendarDbConnection.Connect = function() {
return sql.connect(config.mssql);
}

calendarDbConnection.getAll = function () {
var promise = new sql.Request()
.query('select * from CalendarTable')
.catch(function (err) {
console.log(err.message);
});
return promise;
}

module.exports = calendarDbConnection;


However while running my test, I get following output:

enter image description here

When I call the
done()
after my last
then()
, the function gets resolved but the outcome of my test does not. The number of lines I get from the database are over 20 and I check if they are equal to 5. So, my test should fail, but it does not.

//previous code
.then(function (returnValue) {
expect(returnValue.count).to.equal(5); //This should fail, my database records are 20+
});
done();
//...


So this last outcome passes my test, while it should not.

What am I missing here? I am calling the callback function but then my expected outcome is not correct.

Answer

Since You are returning a Promise from the test, you should not pass done as an argument:

Alternately, instead of using the done() callback, you may return a Promise. This is useful if the APIs you are testing return promises instead of taking callbacks.

Although you can pass done to catch call as stated above, it seems more convenient to get rid of done and just return a promise.

it("should get stuff from the database", function () {
    return calendar.Connect() // returns Promise, so no `done`
    .then(function () {
        return calendar.getAll();
    })
    .then(function (returnValue) {
        expect(returnValue.count).to.equal(5);
    });
});
Comments