Zlatko
Zlatko

Reputation: 19578

Mocha, should.js, and Promise catch callback

I am trying to assert a proper error message in an async promise failure test with mocha, but my test is not passing and I don't know why.

Here's the code - the promise is

'use strict';

let getFailingPromise = function() {

  return new Promise(function(resolve, reject) {

    // simply fail on the next tick
    setTimeout(function() {

      reject(new Error('No reason.'));
    });
  });
}

describe('failing promise catcher', function() {

  it('should fail and I should catch it', function(done) {

    let promise = getFailingPromise();
    promise.catch(function(err) {

      console.log('Error message:', err.message); // => Error message: No reason.
      console.log(err.message === 'No reason.');  // => true
      err.message.should.equal('No reason.');
      done();                                     // => Never reached.
    });
  });
});

I know about Mocha not being able to catch async exceptions. But the code above is all clean, no errors are thrown - or there shouldn't be any.

Edit: Adding output of the call:

[zlatko@obelix ~/tmp]$ mocha test.spec.js 


  failing promise catcher
Error message: No reason.
true
    1) should fail and I should catch it


  0 passing (2s)
  1 failing

  1) failing promise catcher should fail and I should catch it:
     Error: timeout of 2000ms exceeded
      at null.<anonymous> (/usr/lib/node_modules/mocha/lib/runnable.js:158:19)
      at Timer.listOnTimeout (timers.js:89:15)

What am I not understanding?

Upvotes: 1

Views: 964

Answers (2)

haipham23
haipham23

Reputation: 476

You can do like this:

promise.catch(function(err) {
  done(err.message !== 'No reason.' ? new Error('Failed') : undefined);                                     // => Never reached.
});

Upvotes: 0

robertklep
robertklep

Reputation: 203514

You're probably not loading should to implement err.message.should.equal(), so an exception is thrown by the runtime.

Generally, exceptions thrown within a .catch() will be ignored unless you add another .catch() clause to your promise chain (as @Bergi suggests in the comments).

Another option would be to use a more elaborate promises implementation that would warn you about unhandled rejections, like bluebird, which would have shown you this:

Unhandled rejection TypeError: Cannot read property 'equal' of undefined
at ...

Upvotes: 1

Related Questions