Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to test promises with Mocha

I'm using Mocha to test an asynchronous function that returns a promise.

What's the best way to test that the promise resolves to the correct value?

like image 882
Jo Liss Avatar asked Feb 25 '13 01:02

Jo Liss


2 Answers

Mocha has built-in Promise support as of version 1.18.0 (March 2014). You can return a promise from a test case, and Mocha will wait for it:

it('does something asynchronous', function() { // note: no `done` argument
  return getSomePromise().then(function(value) {
    expect(value).to.equal('foo');
  });
});

Don't forget the return keyword on the second line. If you accidentally omit it, Mocha will assume your test is synchronous, and it won't wait for the .then function, so your test will always pass even when the assertion fails.


If this gets too repetitive, you may want to use the chai-as-promised library, which gives you an eventually property to test promises more easily:

it('does something asynchronous', function() {
  return expect(getSomePromise()).to.eventually.equal('foo');
});

it('fails asynchronously', function() {
  return expect(getAnotherPromise()).to.be.rejectedWith(Error, /some message/);
});

Again, don't forget the return keyword!

like image 77
Jo Liss Avatar answered Oct 14 '22 23:10

Jo Liss


Then 'returns' a promise which can be used to handle the error. Most libraries support a method called done which will make sure any un-handled errors are thrown.

it('does something asynchronous', function (done) {
  getSomePromise()
    .then(function (value) {
      value.should.equal('foo')
    })
    .done(() => done(), done);
});

You can also use something like mocha-as-promised (there are similar libraries for other test frameworks). If you're running server side:

npm install mocha-as-promised

Then at the start of your script:

require("mocha-as-promised")();

If you're running client side:

<script src="mocha-as-promised.js"></script>

Then inside your tests you can just return the promise:

it('does something asynchronous', function () {
  return getSomePromise()
    .then(function (value) {
      value.should.equal('foo')
    });
});

Or in coffee-script (as per your original example)

it 'does something asynchronous', () ->
  getSomePromise().then (value) =>
    value.should.equal 'foo'
like image 35
ForbesLindesay Avatar answered Oct 15 '22 00:10

ForbesLindesay