Chai: "expect to throw" not working as expected

Created on 14 Nov 2016  Â·  5Comments  Â·  Source: chaijs/chai

Chai version: 3.5.0

New to using Chai so may not be using it correctly, but my "expect .to.throw" tests are not working correctly (contrast with working try/catch version):

/*jshint node:true, mocha:true, expr:true*/
'use strict';

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

function Foo () {
    this._instance = false;
}

Foo.prototype.init = function () {
    if (this._instance) {
        throw new Error('Already initialised');
    }

    this._instance = true;
};

Foo.prototype.bar = function () {
    if (!this._instance) {
        throw new Error('Not intialised');
    }
};

describe('test - normal', function () {
    var foo = new Foo();

    it('throws exception when not initialised', function () {
        expect(foo.bar).to.throw('Not intialised');
    });

    it('initialise', function () {
        expect(foo.init).to.be.ok;
        expect(foo.bar).to.be.ok;
    });

    it('throws exception when re-initialised', function () {
        expect(foo.init).to.throw('Already initialised');
    });
});

describe('test - try/catch', function () {
    var foo = new Foo();

    it('throws exception when not initialised', function () {
        try {
            foo.bar();

        } catch (e) {
            expect(e.message).to.equal('Not intialised');
        }
    });

    it('initialise', function () {
        expect(foo.init).to.be.ok;
        expect(foo.bar).to.be.ok;
    });

    it('throws exception when re-initialised', function () {
        try {
            foo.init();

        } catch (e) {
            expect(e.message).to.equal('Already intialised');
        }
    });
});

returns:

  test - normal
    1) throws exception when not initialised
    ✓ initialise
    2) throws exception when re-initialised

  test - try/catch
    ✓ throws exception when not initialised
    ✓ initialise
    ✓ throws exception when re-initialised


  4 passing (11ms)
  2 failing

  1) test - normal throws exception when not initialised:
     AssertionError: expected [Function] to throw error including 'Not intialised' but got 'Cannot read property \'_instance\' of undefined'
      at Context.<anonymous> (test/testSpec.js:28:33)

  2) test - normal throws exception when re-initialised:
     AssertionError: expected [Function] to throw error including 'Already initialised' but got 'Cannot read property \'_instance\' of undefined'
      at Context.<anonymous> (test/testSpec.js:37:34)
docs fun-size question

Most helpful comment

Hey @borisovg, thanks for the issue.

When expect(foo.bar) is called, it passes bar method to Chai without the context (given strict mode, this would be undefined, not foo) and it causes unexpected error messages.

Please, try expect(() => foo.bar()) or expect(foo.bar.bind(foo)).

All 5 comments

Hey @borisovg, thanks for the issue.

When expect(foo.bar) is called, it passes bar method to Chai without the context (given strict mode, this would be undefined, not foo) and it causes unexpected error messages.

Please, try expect(() => foo.bar()) or expect(foo.bar.bind(foo)).

Thanks @shvaikalesh: using .bind(foo) does indeed work. Still somewhat unexpected. :)

Just to be clear, there's nothing Chai could do programmatically to avoid this issue. However, it might be good to create a "common pitfalls" note at the end of the throw documentation that mentions this pitfall as well as the other common pitfall of passing the result of a function instead of the actual function (e.g., expect(fn()).to.throw();).

Great idea, @meeber! 😄
I've done a PR for that, please let me know if you remember anything else to add there.
Also, it might have a few grammar mistakes since I'm not a native speaker, so I'm counting on your English skills for the review 😆

Is there any preference which style is better to expect error thrown? normal vs try/catch?

Was this page helpful?
0 / 5 - 0 ratings

Related issues

AnAppAMonth picture AnAppAMonth  Â·  3Comments

JuHwon picture JuHwon  Â·  5Comments

danthegoodman picture danthegoodman  Â·  3Comments

domenic picture domenic  Â·  4Comments

zzzgit picture zzzgit  Â·  3Comments