Asynchronous Tests
Learn how to utilize the done method in Jest to indicate that an asynchronous test should wait for an asynchronous call to finish before proceeding.
We'll cover the following...
Introduction to asynchronous tests
In JavaScript and TypeScript, a lot of code we write is asynchronous. This means that we have no control over exactly when a callback will be invoked or a Promise will resolve, as we are waiting for an event to occur that is outside of our control.
This often presents problems in our unit testing, where we need to wait for an asynchronous event to complete before we can continue with our test.
As an example of this, consider the following class:
class MockAsync {executeSlowFunction(complete: (value: string) => void) {setTimeout(() => {complete(`completed`);}, 1000);}}
-
We have a class named
MockAsync
that has a single method namedexecuteSlowFunction
on lines 2–6. -
This function takes a callback function named
complete
on line 4 as its only parameter and then invokes it after1
second (1000 ms).
We might write a test for this class as follows:
describe("failing async tests", () => {it("should wait for callback to complete", () => {let mockAsync = new MockAsync();console.log(`1. calling executeSlowFunction`);let returnedValue!: string;mockAsync.executeSlowFunction((value: string) => {console.log(`2. complete called`);returnedValue = value;});console.log(`3. checking return value`);expect(returnedValue).toBe("completed");});});
Here, we have a test suite named "failing async tests"
and a test named "should wait for callback to complete"
.
What does this test do?
-
The test starts by creating an instance of the
MockAsync
class namedmockAsync
on line 3. -
It then logs a message to the console on line 4 and creates a variable named
returnedValue
on line 5 to hold the value that will be returned by a call to theexecuteSlowFunction
method. -
It then invokes the
executeSlowValueFunction
...