I've got an async function which runs 2000ms and then it'll throw an exception. I am trying to test exactly this behaviour with Mocha / chai, but apparently I am doing it wrong.
That's what I've tried:
First:
expect(publisher.dispatchMessage<ExampleResponseMessage>(message, {}, 2 * 1000)).to.eventually.throw();
This marks the test as passed (52ms runtime) but throws an exception 2s later. So apparently it hasn't awaited the promise of that function at all.
Second:
expect(async () => {
await publisher.dispatchMessage<ExampleResponseMessage>(message, {}, 2 * 1000);
}).to.throw();
The test fails with: should reject a scheduled message after a predefined timeout: AssertionError: expected [Function] to throw an error at Context.mocha_1.it (test\integration\rpc-communication.spec.ts:75:16) at
Expected behaviour is that the test passed because an exception is thrown after 2000ms, which is within the given test case timeout of 4000ms.
Additional information:
This would work. The promise is rejected with an error (I can also change it to reject with a string). That should proove that dispatchMessage() is working as intended. The test case takes 2002ms and passes then.
try {
await publisher.dispatchMessage<ExampleResponseMessage>(message, {}, 2 * 1000);
} catch (err) {
expect(err).to.be.an('Error');
}
Question:
How do I properly test if an async function throws an exception?
.to.throw()
shouldn't work on async
function because it doesn't throw an error, it returns rejected promise.
The problem is specific to chai-as-promised. As explained in this issue, .to.eventually.throw()
won't work as expected. It asserts that a promise resolves with a function that will throw error synchronously when called. This is likely not what happens in dispatchMessage
.
This depends on dispatchMessage
but likely should be:
expect(publisher.dispatchMessage<ExampleResponseMessage>(message, {}, 2 * 1000))
.to.be.rejected;