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! ;-)