How do I get a meaningful test error when assertion is in a promise?

152 Views Asked by At

I'm having a hard time getting meaningful failures in tests when I need to check things in a promise.

That's because most testing frameworks use throw when an assertion fails, but those are absorbed by the then of promises...

For example, in the following I'd like Mocha to tell me that 'hello' isn't equal to 'world'...

Promise.resolve(42).then(function() {
  "hello".should.equal("world") 
})

Complete fiddle here

With Mocha we can officially return the promise, but this swallows completely the error and is thus much worse...

Note: I'm using mocha and expect.js (as I want to be compatible with IE8)

3

There are 3 best solutions below

5
On BEST ANSWER

With Mocha we can officially return the promise, but this swallows completely the error and is thus much worse...

In your fiddle, you are using Mocha 1.9 which dates from April 2013, and did not support returning promises from tests. If I upgrade your fiddle to the latest Mocha, it works just fine.

0
On

This is less of an answer rather than a suggestion? Using the before hook would be useful here.

describe('my promise', () => {

  let result;
  let err;

  before(done => {
    someAsync()
      .then(res => result = res)
      .then(done)
      .catch(e => {
        err = e;
        done();
      });
  });

  it('should reject error', () => {
    err.should.not.be.undefined(); // I use chai so I'm not familiar with should-esque api
    assert.includes(err.stack, 'this particular method should throw')
  });

});

You could also use sinon to make synchronous mocks and then use whatever should.throw functionality your assertion library provides.

5
On

To test a failing Promise, do this:

it('gives unusable error message - async', function(done){
  // Set up something that will lead to a rejected promise.
  var test = Promise.reject(new Error('Should error'));

  test
    .then(function () {
      done('Expected promise to reject');
    })
    .catch(function (err) {
      assert.equal(err.message, 'Should error', 'should be the error I expect');
      done();
    })
    // Just in case we missed something.
    .catch(done);
});