Chai expect doesn't fail the test if it is inside a callback

Viewed 298

so this test no matter what I do, doesn't fail.

it("should not save the user(duplicate user)", function (done) {
        const user = {
            name: "faruk",
            email: "faruk@farukmail.com",
            password: "faruk2356",
        };
        model.saveUser(user, function (err, doc) {
            expect(err).to.exist;
            done()
        });
    });

If I Console.log the error it shows this:

AssertionError: expected null to exist.

So there is an error but the test doesn't fail. and the errors isn't even related to the save user function it's the error that chai throws. how is that even possible when I console.log(err) it logs not the error callback gives but the error chai throws. I can't understand what is going on here.

3 Answers

You are using callback style, and it seems it doesn’t throw an error; instead returns as an error object. That's why it doesn’t fail.

var chai = require("chai")
var expect = chai.expect;

it("should not save the user(duplicate user)", function (done) {
    const user = {
        name: "faruk",
        email: "faruk@farukmail.com",
        password: "faruk2356",
    };

    model.saveUser(user, function (err, doc) {
        expect(err).to.be.null
// or check if an error exists and throw it
        if(err)
           throw err

          done()
    });

});

var model = {
    saveUser: (user, callback) => {
        // user save function
        callback(new Error('Unable to save user'))
    }
}

Or, you can throw the error inside the saveUser function.

var chai = require("chai")
var expect = chai.expect;

it("should not save the user(duplicate user)", function (done) {
    const user = {
        name: "faruk",
        email: "faruk@farukmail.com",
        password: "faruk2356",
    };

    model.saveUser(user, function (err, doc) {
        done()
    });

});

var model = {
    saveUser: (user, callback) => {
        try {
            // user save function
            throw new Error('Save user failed')
        }
        catch (e ){
            throw e
            // throw an error instead passing it to callback
        }
    }
}
I hope this will help.

You can use assert with chai instead it provides the notEqual method for checking double equals (==) and strictNotEqual for triple equals (===)

You can also write tests using assertions like isNull

const chai = require("chai");
const assert = chai.assert;

suite("User", () => {
  const USER_SAVE_ERROR_MSG = 'User exists already';

  const model = {
    saveUser: (user, callback) => {
      // user save function
      callback(new Error(USER_SAVE_ERROR_MSG))
    }
  }

  it("should not save the user(duplicate user)", (done) => {
    const user = {
      name: "faruk",
      email: "faruk@farukmail.com",
      password: "faruk2356",
    };

    model.saveUser(user, function(err, doc) {
      // use assert.equal instead of assert.notEqual to fail the test
      assert.notEqual(err, null); 
      // following works equally well
      // assert.isNotNull(err);  --> use assert.isNull to fail the test 
      assert.strictEqual(err.message, USER_SAVE_ERROR_MSG)
      done();
    });
  });
});

This happens because your saveUser is not failing which leads to the err to not be null and the assertion itself is failing because you expect it to be something else than null or undefined as you are using .exists.

Related