Antoine Lehurt

How to test promises with Mocha

Promises are convenient to deal with asynchronous code in JavaScript, but at first glance it can feels tedious when it comes to unit test them.

The first approach might be to unit test promises in the same way as we do with callbacks: by calling the done() function, passed by Mocha, when the promise is completed.

it('should do something async', function (done) {
  asyncCall().then(function (result) {
    expect(result).to.be('foo');
    done();
  });
});

It works fine if the test passes but if it fails, then we don’t get any error report from mocha, at best a timeout error. This is because we don’t handle the case when the promise is rejected. This is where it gets tedious and adds more boilerplate: every time we test a promise, we end up having several done() calls in our test. (which bothers me.)

it('should do something async', function (done) {
  asyncCall()
    .then(function (result) {
      expect(result).to.be('foo');
      done();
    })
    .catch(done);
});

Built in Promises support

Hopefully, Mocha comes with a nice built in support. Instead of having to handle manually failing tests, we can directly return the promise.

it('should do something async', function () {
  return asyncCall().then(function (result) {
    expect(result).to.be('foo');
  });
});

And voilà! Now we don’t need to think about where we need to put the done() calls.

If you want to directly assert your promises, I recommend you to look over Chai promises plugin.