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

ID : 10266

viewed : 18

Tags : javascriptnode.jsmocha.jschaijavascript

Top 5 Answer for javascript - Mocha / Chai expect.to.throw not catching thrown errors

vote vote

93

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.

vote vote

90

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.'); 
vote vote

76

And if you are already using ES6/ES2015 then you can also use an arrow function. It is basically the same as using a normal anonymous function but shorter.

expect(() => model.get('z')).to.throw('Property does not exist in model schema.'); 
vote vote

65

This question has many, many duplicates, including questions not mentioning the Chai assertion library. Here are the basics collected together:

The assertion must call the function, instead of it evaluating immediately.

assert.throws(x.y.z);          // FAIL.  x.y.z throws an exception, which immediately exits the    // enclosing block, so assert.throw() not called. assert.throws(()=>x.y.z);      // assert.throw() is called with a function, which only throws    // when assert.throw executes the function. assert.throws(function () { x.y.z });       // if you cannot use ES6 at work function badReference() { x.y.z }; assert.throws(badReference);      // for the verbose assert.throws(()=>model.get(z));      // the specific example given. homegrownAssertThrows(model.get, z);    //  a style common in Python, but not in JavaScript 

You can check for specific errors using any assertion library:

Node

  assert.throws(() => x.y.z);   assert.throws(() => x.y.z, ReferenceError);   assert.throws(() => x.y.z, ReferenceError, /is not defined/);   assert.throws(() => x.y.z, /is not defined/);   assert.doesNotThrow(() => 42);   assert.throws(() => x.y.z, Error);   assert.throws(() => model.get.z, /Property does not exist in model schema./) 

Should

  should.throws(() => x.y.z);   should.throws(() => x.y.z, ReferenceError);   should.throws(() => x.y.z, ReferenceError, /is not defined/);   should.throws(() => x.y.z, /is not defined/);   should.doesNotThrow(() => 42);   should.throws(() => x.y.z, Error);   should.throws(() => model.get.z, /Property does not exist in model schema./) 

Chai Expect

  expect(() => x.y.z).to.throw();   expect(() => x.y.z).to.throw(ReferenceError);   expect(() => x.y.z).to.throw(ReferenceError, /is not defined/);   expect(() => x.y.z).to.throw(/is not defined/);   expect(() => 42).not.to.throw();   expect(() => x.y.z).to.throw(Error);   expect(() => model.get.z).to.throw(/Property does not exist in model schema./); 

You must handle exceptions that 'escape' the test

it('should handle escaped errors', function () {   try {     expect(() => x.y.z).not.to.throw(RangeError);   } catch (err) {     expect(err).to.be.a(ReferenceError);   } }); 

This can look confusing at first. Like riding a bike, it just 'clicks' forever once it clicks.

vote vote

58

examples from doc... ;)

because you rely on this context:

  • which is lost when the function is invoked by .throw
  • there‚Äôs no way for it to know what this is supposed to be

you have to use one of these options:

  • wrap the method or function call inside of another function
  • bind the context

    // wrap the method or function call inside of another function expect(function () { cat.meow(); }).to.throw();  // Function expression expect(() => cat.meow()).to.throw();             // ES6 arrow function  // bind the context expect(cat.meow.bind(cat)).to.throw();           // Bind 

Top 3 video Explaining javascript - Mocha / Chai expect.to.throw not catching thrown errors

Related QUESTION?