Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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. 
like image 422
doremi Avatar asked Feb 05 '14 19:02

doremi


People also ask

Do mocha and chai go together?

Getting Started Both Mocha and Chai run in NodeJs and the browser and allow asynchronous testing. Although Mocha can be paired with any of the assertion libraries, it is delightfully paired with Chai most of the time. Chai provides us with several APIs like Assert, Expect/Should, and more.

What is a thrown error?

The throw statement throws (generates) an error. The technical term for this is: The throw statement throws an exception. The exception can be a JavaScript String, a Number, a Boolean or an Object: throw "Too big"; // throw a text.

How does throw error work?

throw Error() is like a Javascript string, a number, a boolean, or an object. It returns specific errors as defined in the message value which is passed as an argument. It Creates a new Error object and sets the error. message property to the provided text message.


2 Answers

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.

like image 182
Louis Avatar answered Oct 05 '22 02:10

Louis


As this answer says, you can also just wrap your code in an anonymous function like this:

expect(function(){     model.get('z'); }).to.throw('Property does not exist in model schema.'); 
like image 37
twiz Avatar answered Oct 05 '22 01:10

twiz