Mocha / Chai expect.to.throw not catching thrown errors

doremi picture doremi · Feb 5, 2014 · Viewed 162.6k times · Source

I'm having issues getting Chai's expect.to.throw to work in a test for my node.js app. The test keeps failing on the thrown error, but If I wrap the test case in try and catch and assert on the caught error, it works.

Does expect.to.throw not work like I think it should or something?

it('should throw an error if you try to get an undefined property', function (done) {
  var params = { a: 'test', b: 'test', c: 'test' };
  var model = new TestModel(MOCK_REQUEST, params);

  // neither of these work
  expect(model.get('z')).to.throw('Property does not exist in model schema.');
  expect(model.get('z')).to.throw(new Error('Property does not exist in model schema.'));

  // this works
  try { 
    model.get('z'); 
  }
  catch(err) {
    expect(err).to.eql(new Error('Property does not exist in model schema.'));
  }

  done();
});

The failure:

19 passing (25ms)
  1 failing

  1) Model Base should throw an error if you try to get an undefined property:
     Error: Property does not exist in model schema.

Answer

Louis picture Louis · Feb 5, 2014

You have to pass a function to expect. Like this:

expect(model.get.bind(model, 'z')).to.throw('Property does not exist in model schema.');
expect(model.get.bind(model, 'z')).to.throw(new Error('Property does not exist in model schema.'));

The way you are doing it, you are passing to expect the result of calling model.get('z'). But to test whether something is thrown, you have to pass a function to expect, which expect will call itself. The bind method used above creates a new function which when called will call model.get with this set to the value of model and the first argument set to 'z'.

A good explanation of bind can be found here.