Better asynchronous tests with mocha, co and async/await

As you probably know mocha supports two ways for testing asynchronous functions. The first one is adding a done callback to it() like so:

describe("some async function", function () {
  it("should do something", function (done) {
    myAsyncOperation(params)
      .then(function (error, result) {
        if (error) {
          done(error);
          return;
        }

        // assertions on result ...
      })
      .then(done)
      .catch(done);
  });
});

The second one is to return a promise:

describe("some async function", function () {
  it("should do something", function () {
    return myAsyncOperation(params)
      .then(function (result) {
        // assertions on result ...
      });
  });
});

Returning a promise plays really nicely with co which takes a generator function and turns it into a promise-returning function.

describe("some async function", function () {
  it("should do something", () => co(function* () {
    const result = yield myAsyncOperation(params);

    // assertions on result ...
  }));
});

Notice that myAsyncOperation does not need to change at all. It just needs to return a promise like before. co will "pause" the generator function for you until the promise is resolved or rejected. You can use seemingly synchronous code (including try/catch) inside the generator.

With NodeJS 7 you can take this pattern to the next level using async/await:

describe("some async function", function () {
  it("should do something", async function () {
    const result = await myAsyncOperation(params);

    // assertions on result ...
  });
});

This almost looks like the co solution but removes the need for an additional library.

I like this pattern a lot and will definitely use it more in the future.

Happy async testing! ;-)