I am writing automated integration tests with Mocha and Chai. Here is a simplified version of the code I am testing:
exports.doSomething = async function (req, res) {
return executeRequest(req.body)
.then((response) => {
console.log("then running");
res.status(200).send(response);
})
.catch((err) => {
console.error(err);
res.status(500).send(err);
}
}
And here is what my test file looks like:
const { doSomething } = require("../../index");
const { assert } = require("chai");
const { stub } = require("sinon");
const req = { body: { *data* } };
const res = {
status: stub().returnsThis(),
send: stub().returnsThis(),
};
it(`Please work`, async () => {
await doSomething(req, res);
}
When that happens, neither the .then block nor the .catch blocks are entered—console.log does not run; res.send and res.status are never called.
Another interesting note: If I remove the async from the test call and save the result of doSomething() to a variable, it shows as a promise. When I include the async, the result of doSomething is undefined.
I am new to Mocha and have no idea why it seems to be ignoring the asynchronicity of the code.
Your doSomething implementation is broken, the promise that the async function returns will fulfill immediately - before executeRequest is done. You should write either
exports.doSomething = function (req, res) {
return executeRequest(req.body)
//^^^^^^
.then((response) => {
console.log("then running");
res.status(200).send(response);
})
.catch((err) => {
console.error(err);
res.status(500).send(err);
})
}
or
exports.doSomething = async function (req, res) {
try {
const response = await executeRequest(req.body);
// ^^^^^
console.log("then running");
res.status(200).send(response);
} catch(err) {
console.error(err);
res.status(500).send(err);
}
}
Only then your test can properly await the doSomething(req, res) call, and mocha won't prematurely kill the process.