- [Instructor] Jest supports asynchronous code
without the use of any third-party plugins.
Three styles are supported.
The first are callbacks,
which have been around for quite a while.
There's also promises which are more modern
and a flexible technique.
Finally, there's async/await,
which is syntactic sugar for promises.
We'll look at callbacks and promises first,
then the challenge will be to use async/await.
Let's start testing asynchronous callbacks with Jest.
By default, Jest tests complete at the end of execution.
An asynchronous callback won't be called
until the function executes.
Therefore, if we wrote a test like we did before,
the test will already be completed
before we can check to see if it succeeded or not.
Here's an example of an asynchronous callback.
We'll start with a simple function
toTest which takes a callback.
I'm going to use set immediate
to asynchronously execute the callback,
and arbitrarily return the word yay.
With that in mind, here's an incorrectly written test.
Don't do it this way.
Test the wrong way to test a callback
and an arrow function expression.
Then we'll define a function for the callback,
which takes value.
It uses Jest expect to compare the value
to the word no, which will fail.
At the end, call toTest with a callback.
The callback will execute,
but because it's asynchronous,
the Jest test will complete
before the actual callback returns.
The joys of the event loop.
The solution, is an alternate version of test and it,
which returns a callback typically called done.
If the done callback is provided,
Jest will wait until the done callback is called,
before the test is considered finished.
If it hasn't been called, the test will time out,
which by default will take five seconds.
Another use of done is to throw if given a value,
which is useful for checking for unexpected errors.
With that in mind, here's the correct way
to write that asynchronous callback.
Test the right way to test a call back,
and give it a call back named done.
Now, function call back takes a value,
but this time we're going to try the expectation
which we'll throw if it fails,
then call done afterwards
In the catch, done can accept an argument
which is the error.
Done will fail if it receives a value,
which is what we want.
For the execution, toTest with the value of the callback
works the same way.
While you can write callback tests
without the try and catch,
the test will pass,
but the failures won't be handled correctly.
What are the consequences of writing
an asynchronous callback test incorrectly?
Switch over to VS Code,
go up to file, and then open folder.
Navigate to wherever you have the exercise files,
and go to sandbox.
Open up 03 06 and click select folder.
Open up a terminal and then install the dependencies,
which is just Jest, so type MPM-install and press enter.
We're going to try two different orders.
In the Explorer, select wrong right.
At the top is the function to be tested.
Then the wrong way to test,
followed by the right way to test.
What happens when we execute it?
Switch to the terminal.
Type MPX Jest then wrong-right.test.JS,
and press enter
The test fails and fails rather oddly.
If we scroll up to the top,
the list of tests at the top
shows that the wrong way to test passed which is incorrect,
and the right way to test failed, which is what we expected.
However, the breakdown of the errors
first shows the wrong way to test,
followed by the right way to test.
What? That's confusing.
Can you imagine trying to track that down
in a real code base?
Close out wrong right, then choose right wrong.
It's the exact same two tests,
but the test order is switched,
so the right way to test a callback executes first.
What happens when we run it?
Switch to the terminal.
Type MPXJestright-wrong.test.JS, and press enter.
Jest crashed the test through an uncaught exception
which we see described.
If we look at the stack trace,
we can figure out where it failed.
Callback online 20, position 19.
However, it's not displayed cleanly
and Jest didn't get an opportunity
to make the report on overall execution
Close out the terminal and close right wrong.
In summary, when testing a callback,
you need to give it a test
or a named callback function typically named done.
You should wrap your asynchronous tests with a try and catch
in order to guarantee that Jest can handle any errors.
Otherwise Jest might crash
if there was a problem with one of the tests.
That's enough theory.
Let's write our first
asynchronous callback test suite in Jest.