Skip to content

Asynchronous Code

By adding an argument (usually named done) to it() to a test callback, Mocha will know that it should wait for this function to be called to complete the test. This callback accepts both an Error instance (or subclass thereof) or a falsy value; anything else is invalid usage and throws an error (usually causing a failed test).

describe("User", function () {
describe("#save()", function () {
it("should save without error", function (done) {
var user = new User("Luna");
user.save(function (err) {
if (err) done(err);
else done();
});
});
});
});

Alternatively, use the done() callback directly (which will handle an error argument, if it exists):

describe("User", function () {
describe("#save()", function () {
it("should save without error", function (done) {
var user = new User("Luna");
user.save(done);
});
});
});

Working with Promises

Alternately, instead of using the done() callback, you may return a Promise. This is useful if the APIs you are testing return promises instead of taking callbacks:

beforeEach(function () {
return db.clear().then(function () {
return db.save([tobi, loki, jane]);
});
});
describe("#find()", function () {
it("respond with matching records", function () {
return db.find({ type: "User" }).should.eventually.have.length(3);
});
});

In Mocha v3.0.0 and newer, returning a Promise and calling done() will result in an exception, as this is generally a mistake:

const assert = require("assert");
// antipattern
it("should complete this test", function (done) {
return new Promise(function (resolve) {
assert.ok(true);
resolve();
}).then(done);
});

The above test will fail with Error: Resolution method is overspecified. Specify a callback *or* return a Promise; not both. In versions older than v3.0.0, the call to done()` is effectively ignored.

Using async / await

If your JS environment supports async / await, you can also write asynchronous tests like this:

beforeEach(async function () {
await db.clear();
await db.save([tobi, loki, jane]);
});
describe("#find()", function () {
it("responds with matching records", async function () {
const users = await db.find({ type: "User" });
users.should.have.length(3);
});
});

Limitations of asynchronous callbacks

You can use all asynchronous callbacks (done, Promise, and async/await) in callbacks for it(), before(), after(), beforeEach(), afterEach()) but not describe() — it must be synchronous. See #5046 for more information.

Synchronous Code

When testing synchronous code, omit the callback and Mocha will automatically continue on to the next test.

describe("Array", function () {
describe("#indexOf()", function () {
it("should return -1 when the value is not present", function () {
[1, 2, 3].indexOf(5).should.equal(-1);
[1, 2, 3].indexOf(0).should.equal(-1);
});
});
});