VOOZH about

URL: https://www.javacodegeeks.com/2021/12/testing-promise-rejection-in-javascript-with-jest.html

⇱ Testing promise rejection in JavaScript with Jest - Java Code Geeks


The code

Let’s consider a simple function that returns a Promise that can either resolve or reject depending on the value of
the first argument:

export default function promiseMe(result, timeout = 1000) {
 return new Promise((resolve, reject) => {
 setTimeout(() => {
 if (result instanceof Error || result.startsWith("Error")) {
 reject(result)
 } else {
 resolve(result)
 }
 }, timeout)
 })
}

While testing async code with Jest the only thing to remember is to return Promise from the test so that Jest can
wait for it to resolve or to reject. The cleanest way is to do it with .resolves matcher:

const successMessage = "Done.";

// with async/await
it("resolves (1)", async () => {
 await expect(promiseMe(successMessage)).resolves.toEqual(successMessage);
});

// without async/await
it("resolves (2)", () => {
 return expect(promiseMe(successMessage)).resolves.toEqual(successMessage);
});

In case the Promise rejects and the test did not expect that, Jest reports an error:

Error: expect(received).resolves.toEqual()

Received promise rejected instead of resolved
Rejected to value: [...]

But what if one want to test Promise rejection and verify the rejection reason?

Try-catch with async/await (bad)

It looks like using try-catch with async/await is the easiest way to achieve this as the rejected value is thrown:

it("rejects (bad)", async () => {
 try {
 await promiseMe("Error");
 } catch (e) {
 expect(e).toEqual("Error");
 }
});

But wait. What happens when the Promise returned by promiseMe function won’t reject, but it resolves instead? Well, the test still passes, as the catch block is never reached.

See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/await#promise_rejection

Try-catch with async/await (better)

To overcome that issue, one could expect that the actual assertion will be executed and fail the test if it does not happen.
This can be done pretty easily with expect.assertions which verifies that a certain number of assertions are called
during a test:

it("rejects (better)", async () => {
 expect.assertions(1);
 try {
 await promiseMe("Error");
 } catch (e) {
 expect(e).toEqual("Error");
 }
});

Now, when there is no rejection, the test fails:

Error: expect.assertions(1)

Expected one assertion to be called but received zero assertion calls.

.rejects (best)

To make the code even more expressive .rejects matcher can be used:

it("rejects (best)", async () => {
 await expect(promiseMe("Error")).rejects.toEqual("Error");
});

When there is no rejection, Jest reports an error:

Error: expect(received).rejects.toEqual() 
 
Received promise resolved instead of rejected 
Resolved to value: [...]

If the rejected value is an Error object, toThrow matcher can be used:

it("rejects (best)", async () => {
 await expect(promiseMe(new Error(errorMessage))).rejects.toThrow(errorMessage);
 await expect(promiseMe(new Error(errorMessage))).rejects.toThrow(Error); // type check
 await expect(promiseMe(new Error(errorMessage))).rejects.toThrow(new Error(errorMessage));
});

Published on Java Code Geeks with permission by Rafal Borowiec, partner at our JCG program. See the original article here: Testing promise rejection in JavaScript with Jest

Opinions expressed by Java Code Geeks contributors are their own.

Do you want to know how to develop your skillset to become a Java Rockstar?
Subscribe to our newsletter to start Rocking right now!
To get you started we give you our best selling eBooks for FREE!
1. JPA Mini Book
2. JVM Troubleshooting Guide
3. JUnit Tutorial for Unit Testing
4. Java Annotations Tutorial
5. Java Interview Questions
6. Spring Interview Questions
7. Android UI Design
and many more ....
I agree to the Terms and Privacy Policy

Thank you!

We will contact you soon.

Tags
Testing
πŸ‘ Photo of Rafal Borowiec
Rafal Borowiec
December 13th, 2021Last Updated: December 3rd, 2021
0 2,457 2 minutes read

Rafal Borowiec

Software developer, Team Leader, Agile practitioner, occasional blogger, lecturer. Open Source enthusiast, quality oriented and open-minded.
Subscribe

This site uses Akismet to reduce spam. Learn how your comment data is processed.

0 Comments
Oldest
Newest Most Voted
Back to top button
Close
wpDiscuz