Reputation: 6477
In my mocha.js test, I'm calling an async
function that throws an error, but the test doesn't fail. It passes and there is an UnhandledPromiseRejectionWarning
:
describe('async function', async function () {
it('should fail', async function () {
[1].forEach(async function () {
throw new Error("Why can't I see this error?!");
});
});
});
Note, that a simpler case works as expected:
describe('async function', async function () {
it('should fail', async function () {
throw new Error('This one fails the test');
});
});
How can I cause the test to fail due to an exception in an inner function?
(I've tried adding an unhandledRejection
handler, but the test still passes)
Upvotes: 0
Views: 446
Reputation: 816910
Louis' answer is spot on. As an alternative, you could avoid using an inner function and use a normal for
loop instead:
const data = [1];
for (let i = 0; i < data.length; i++) {
// await some more stuff here
throw new Error('This one fails the test');
}
Upvotes: 3
Reputation: 151491
Your test case with .forEach
cannot work like you want it to work. When it calls its async callback, the callback does create a promise, but .forEach
does not do anything with it. The callback you pass to it
is async too and it does return a promise, but the promise it returns is not connected to the promises that the callback to .forEach
produces. That's why you get UnhandledPromiseRejectionWarning
.
You can solve the issue by connecting the promises through Promise.all
:
describe('async function', async function () {
it('should fail', async function () {
return Promise.all([1].map(async function () {
throw new Error("Why can't I see this error?!");
}));
});
});
Using map
makes it so that your array is turned into an array of promises, and then Promise.all
waits for all the promises in the array to be resolved, or it rejects if any promise rejects. Returning the return value of the Promise.all
call then allow Mocha to wait for the whole thing.
Upvotes: 3