Chai: 'then' function is not never getting called by Mocha for assertion checking

Created on 22 Jan 2015  路  1Comment  路  Source: chaijs/chai

I have written the following test case in Mocha, where the my code uses Q module.

var expect = require("chai").expect;
var utils = require("../Utils.js");
var utils1 = require("../a.js");
var sinon = require('sinon');
var request = require('requestretry');
var querySys = require('../b.js');
var Q = require("q");

describe("Sample", function () {
    var results;
    describe("#get()", function () {
        before(function (done) {
            done();
        });
        it("equal", function () {
            var deferred = Q.defer();
            var responseData = {};
            responseData.code = 200;
            responseData.data = [{a:1,b:2}];
            deferred.resolve(responseData);
            //querySys1 method uses Q promises. That is how I stubbed the response.
            sinon.stub(querySys, 'querySys1').returns(deferred.promise);

            //get function internally calls querySys1. Hence I have stubbed that.
            results = utils1.get(specification);
            results.then(function (data) {
                //Here I do see data coming as {in:1, out:1}. But still the test case is passing when compare it with {}.
                console.log(data);
                //Ideally, it should have failed. But it is passing.
                expect(data).to.be.equal({});
            });
        });
        after(function (done) {
            done();
        })
    });
});

So, if you see, I am trying to do assertion check in results.then part. I have printed the response, which I am receiving. That is coming as expected. But I am intentionally trying to match with wrong value, but test case is still passing.

question

Most helpful comment

Hey @prachicsa thanks for the issue! I think I see the problem here.

Because you're running asynchronous code in your it, the it test itself needs to be async. It looks like you've tried to make it async with the before and after steps, but I think you've done it wrong. You need to pass the done param to the it test (as documented here). This is what your test should look like:

var expect = require("chai").expect;
var utils = require("../Utils.js");
var utils1 = require("../a.js");
var sinon = require('sinon');
var request = require('requestretry');
var querySys = require('../b.js');
var Q = require("q");

describe("Sample", function () {
    var results;
    describe("#get()", function () {

        it("equal", function (done) {
            var deferred = Q.defer();
            var responseData = {};
            responseData.code = 200;
            responseData.data = [{a:1,b:2}];
            deferred.resolve(responseData);
            //querySys1 method uses Q promises. That is how I stubbed the response.
            sinon.stub(querySys, 'querySys1').returns(deferred.promise);

            //get function internally calls querySys1. Hence I have stubbed that.
            results = utils1.get(specification);
            results.then(function (data) {
                expect(data).to.be.equal({});
            }).then(done, done);
        });

    });
});

Alternatively Mocha lets you return a promise inside the it which will make it async. So you could write it as:

var expect = require("chai").expect;
var utils = require("../Utils.js");
var utils1 = require("../a.js");
var sinon = require('sinon');
var request = require('requestretry');
var querySys = require('../b.js');
var Q = require("q");

describe("Sample", function() {
    var results;
    describe("#get()", function() {

        it("equal", function() {
            var deferred = Q.defer();
            var responseData = {};
            responseData.code = 200;
            responseData.data = [{
                a: 1,
                b: 2
            }];
            deferred.resolve(responseData);
            //querySys1 method uses Q promises. That is how I stubbed the response.
            sinon.stub(querySys, 'querySys1').returns(deferred.promise);

            //get function internally calls querySys1. Hence I have stubbed that.
            return utils1.get(specification)
                .then(function(data) {
                    expect(data).to.be.equal({});
                });
        });

    });
});

Hopefully this works for you. I'm going to close the issue now, but please say it if you're still having trouble and we'll get to the bottom of it!

>All comments

Hey @prachicsa thanks for the issue! I think I see the problem here.

Because you're running asynchronous code in your it, the it test itself needs to be async. It looks like you've tried to make it async with the before and after steps, but I think you've done it wrong. You need to pass the done param to the it test (as documented here). This is what your test should look like:

var expect = require("chai").expect;
var utils = require("../Utils.js");
var utils1 = require("../a.js");
var sinon = require('sinon');
var request = require('requestretry');
var querySys = require('../b.js');
var Q = require("q");

describe("Sample", function () {
    var results;
    describe("#get()", function () {

        it("equal", function (done) {
            var deferred = Q.defer();
            var responseData = {};
            responseData.code = 200;
            responseData.data = [{a:1,b:2}];
            deferred.resolve(responseData);
            //querySys1 method uses Q promises. That is how I stubbed the response.
            sinon.stub(querySys, 'querySys1').returns(deferred.promise);

            //get function internally calls querySys1. Hence I have stubbed that.
            results = utils1.get(specification);
            results.then(function (data) {
                expect(data).to.be.equal({});
            }).then(done, done);
        });

    });
});

Alternatively Mocha lets you return a promise inside the it which will make it async. So you could write it as:

var expect = require("chai").expect;
var utils = require("../Utils.js");
var utils1 = require("../a.js");
var sinon = require('sinon');
var request = require('requestretry');
var querySys = require('../b.js');
var Q = require("q");

describe("Sample", function() {
    var results;
    describe("#get()", function() {

        it("equal", function() {
            var deferred = Q.defer();
            var responseData = {};
            responseData.code = 200;
            responseData.data = [{
                a: 1,
                b: 2
            }];
            deferred.resolve(responseData);
            //querySys1 method uses Q promises. That is how I stubbed the response.
            sinon.stub(querySys, 'querySys1').returns(deferred.promise);

            //get function internally calls querySys1. Hence I have stubbed that.
            return utils1.get(specification)
                .then(function(data) {
                    expect(data).to.be.equal({});
                });
        });

    });
});

Hopefully this works for you. I'm going to close the issue now, but please say it if you're still having trouble and we'll get to the bottom of it!

Was this page helpful?
0 / 5 - 0 ratings

Related issues

domenic picture domenic  路  4Comments

andipavllo picture andipavllo  路  3Comments

qbolec picture qbolec  路  5Comments

zzzgit picture zzzgit  路  3Comments

endymion00 picture endymion00  路  3Comments