Jake Wilson Jake Wilson - 26 days ago 7
Javascript Question

How to assert in async function within Promise?

When using Mocha for unit testing, I have a situation like this that I need to test:

it('should assert true blah blah blah', function () {

return doSomething() // <-- returns a Promise
.then(function(value) {

return setTimeout(function() {

assert.equal(something, true);

},1000);

});

});


So I have a Promise that is returned from a function, and then I need to do an assert within an async
setTimeout
after the Promise has been resolved. The above code appears to always pass the test no matter what. In fact, it seems like the
setTimeout
never ever runs. If I put a
console.log
in the
setTimeout
it never prints out. Mocha finishes the unit test and moves on.

What is the proper way to test something like this? I see there is some sort of
done()
method with Mocha but I'm not sure if that is something I should use with this or not. I don't fully understand it.

Answer

If you return a promise to Mocha, it will assume the test is complete when the promise resolves.

If you have some non-promise-based asynchronous function to test after the promise resolves, you can use a done callback instead of returning a promise:

it('should assert true blah blah blah', function (done) {

  doSomething()
    .then(function(value) {

      setTimeout(function() {

        assert.equal(something, true);
        done();

      },1000);

    })
    .catch(done);
});

Note that you should also include a catch so that any promise rejection is passed to the done callback, as Mocha understands Node-style errors and will fail the test if it receives one.

Alternatively, you could use a completely promise-based approach and could create a Promise to enclose your asynchronous function:

it('should assert true blah blah blah', function () {

  return doSomething()
    .then(function(value) {

      return new Promise(function (resolve, reject) {

        setTimeout(function() {

          try {
            assert.equal(something, true);
            resolve();
          } catch (error) {
            reject(error);
          }

        },1000);

      });
    });
});
Comments