Testing Asynchronous Code
When you have code that runs asynchronously, Jest needs to know when the code it is testing has completed before moving to another test.
We are going to test the below function that runs asynchronously and gets data from API.
In the above code snippet AllUsers handle the result of fetched data by getUsers from database. We have used the response of the GET request (res) to send the result or handle the error of the getUsers().
There are three approaches to handle this:
1: Using Callbacks
To test asynchronous code using callbacks, you just need to put the test in a function with a single argument called done. Jest will wait until the done ****callback is called before finishing the test.
test/router/users.test.js
If done() callback is never called, the test will fail with no error.
2: Using Promises
To write a test using promise, you need just to return a promise from your test. The below test returns a promise that is supposed to resolve a response and Jest will wait to resolve and if rejected test will fail automatically.
test/router/users.test.js
3: Using Async/Await
If your code uses Async/Await, you can use these in your tests as well.
To write an Async test, use the async keyword in front of the function passed to test.
code example:
test/router/users.test.js
<aside>💡 Jest will throw an error, if the same test function is passed a done() callback and returns a promise. This is done as a precaution to avoid memory leaks in your tests.
</aside>
Resolves/ Rejects matchers
You can also use resolves and rejects matchers to test asynchronous code. And jest will wait for that promise to resolve or reject it.
In the above test expect.assertions(1) used in order to verify that a certain number of assertions are called during the test. or you can use expect.hasAssertions() instead of expect.assertions(number) which verifies that at least one assertion is called during a test.
If you don't add expect.assertions(number) or expect.hasAssertions() to verify that assertions are called a fulfilled promise will not fail the test.
You can also combine resolves and rejects with async/await :