In this lesson you're going to continue to explore testing and the goal here is to figure out how we
can test asynchronous code using jest.
Now it's gonna look super similar to what we've already done when testing our synchronous code we'll
just be making a couple of small changes to the test cases to get support for testing asynchronous code
with jest.
Now before we even get to that I want to take a quick moment to add a command line argument onto our
just command over here in package Dot.
Jason this is going to keep jest up and running and just will automatically restart rerunning our tests
when either the test case code changes or the code that's being tested changes so it'll be similar to
how node on restarts our node server when we're running in development mode though this time it'll be
doing the same thing for the test cases to configure that all you have to do is add a new command line
option on right here that is hyphen hyphen watch That's it.
Now we can restart our test suite using the same command.
It's still NPM test and it's still going to run those test cases.
But one thing you'll notice is that it doesn't bring you back to the command prompt.
So up above I can see the results of that test suite running.
I have all of the test cases running for passing which is great.
Down below we now have a list of options for when we're in this watch mode.
Now it's automatically going to rerun tests that do change right here.
I could press a to run all tests again and they can use other options to do things like quit the watch
mode with Q So right here I can type a while focused on the terminal to rerun things and I could always
use w to bring those watch options open again.
So this is what we're going to use going forward.
So we don't have to constantly head back to the terminal and manually rerun things as we change our
test cases.
Now if you want to explore other command line options that are supported by jest you can view all of
those over in the documentation to over in the docs sidebar if you scroll way to the bottom.
Under API reference once again that's where we found expect you'll see just CLIA options down below.
This page contains every single command line option you can use in the right hand side bar.
We have a list of all of them.
And if I scroll down near the bottom we have the one that we used right here.
Watch.
And there are a bunch of others.
The watch is the only one we'll actually need.
So with this in place we now have a slightly better setup and we're going to focus on figuring out how
we can test asynchronous code using just let's get started with a very simple test case to illustrate
a specific point.
So right here what I'm gonna do is call the test function and I'll set up this demo test case I can
call it something like a sync test demo and then I'll also go ahead and set up the callback function
to run it which contains the testing code and we're going to do inside of here is use expect to perform
an assertion that is clearly incorrect.
Let's go ahead and do just that I'm going to expect that the number 1 equals using to be the number
two.
Now clearly that's not the case and based off of what we know already I would expect this test case
to fail.
If I save the program that is exactly what happens just automatically restarts rerunning the test suite
and if I scroll up I can see that too it was expected but one was received so async test demo has failed.
Now nothing shocking there.
What we're gonna do though is introduce a little bit of asynchronous programming by simulating it with
set time out and we're going to see how that changes the behavior and the output of this test case running
right here.
We'll call set time out like we've done dozens of times so far.
We'll pass in our callback function in the amount of time we would like to wait.
I'll go ahead and use two seconds by providing two thousand milliseconds as the second argument and
down below.
All we're gonna do is take our call to expect we're going to cut it out of its current location and
paste it right here inside of the callback function.
Now we can go ahead and remove those extra lines and we'll just rerun the test case like we did before.
So what's going to happen while our function is going to run.
It's then going to register a callback function to run after two seconds after two seconds.
This function is going to run and then our assertion will be performed.
So let's go ahead and save the file and then we're gonna count to 2 and it's done.
So what happened.
Clearly it didn't wait those two seconds and clearly something's gone wrong because down below async
test demo is passing even though the assertion we're performing is clearly invalid.
The problem here is that just did it no.
Our test contained asynchronous code so it simply ran the function.
By the time the function was done no error got throw in.
So what did it do it considered the test a success.
It didn't wait for those two seconds to pass to see that the assertion would fail later down the line.
The entire test suite only took less than half a second so it definitely did not wait the time necessary
for this failed assertion to actually run.
Now all we need to do to address this is to add a little bit of extra code to tell jest this is a synchronous.
All we have to do to tell just this function contains a synchronous code is to add a single parameter
onto the callback function.
Now we're going to name this done.
But you could technically call it whatever you wanted and it's your job to call done.
After everything is complete so after your asynchronous process is complete and your assertions have
been made.
So when we provide done as a parameter just sees that and it won't consider this test case a success
or a failure until done is called.
So all I'm going to do is add a call to done right here that will make sure that just actually waits
for set time out to finish and for our assertion to be created and made before figuring out if the test
succeeded or failed.
Now if I save the program we'll notice it actually takes more than two seconds so it is indeed waiting
for those two seconds related to set time out and we can see we have a single failing test which is
perfect if we scroll up to the test case itself a async test demo.
We expected to.
We received one and that's what's causing the test to fail.
So when we're working with asynchronous code we have to make sure that just doesn't consider our test
a success or failure before we've actually finished the asynchronous process.
And this is one approach you provide.
The done parameter and you call done well when you're done.
Now there are other ways we can get this done as well especially when it comes to working with promises
and async await.
So that's what I'd like to talk about next.
Now we are going to need an asynchronous function we can actually test into continue on with our little
demonstration before we worry about testing the task manager app.
We're gonna go ahead and grab one of the functions we created in the playground directory earlier in
the class.
So over in the playground folder down below near the bottom I have async await and I have an add function.
This add function adds up to numbers but it waits 2 seconds first so we're gonna figure out how we could
test this then in the next lesson I promise we'll actually start to test our Express application for
the moment though what we're gonna do is copy this function to the clipboard.
Now if you don't have this in place for whatever reason you can always download the lecture zip for
this lesson to grab it.
So take a moment to do that if you need to.
And we're going to bring this function over to math dot J S I'll add it just below Celsius to Fahrenheit
and I'll make sure to export it down below down here.
I will set up ad as something exporting and I'll save the file.
Now over in the math test file we can go ahead and load that in in our required call up top.
I'll make sure to grab add right here and then down below.
We're actually going to use that inside of a test case.
Now I'm going to leave this one in place for the moment as a demonstration of asynchronous testing.
So down below we'll go ahead and add another call to test to create a new test case to test our promise
based asynchronous function.
The structure of the test case is still the same.
We'll set up a name for this one.
I'll say something like should add two numbers and then I'll go ahead and set up the test case callback
function.
And in this case we are going to provide that done parameter.
So just knows that something asynchronous is happening inside of here and down below.
We're going to go ahead and call add I'll call add adding up the number two and the number three for
the total five now right here what we're going to do is call then allowing us to provide a function
to run when the promise has been fulfilled with a value in this case these sum will get access to these
some right here which is exactly what we explored much earlier in the class when working with promises.
Now inside of here it is our job to do the same thing we were doing up above.
We make our assertions and then we called done so right here.
I will be expecting that the sum equals the number five using to B and passing five in.
Now at this point we'd call done a sense are assertions are in place and we know the asynchronous process
has finished.
If this function is actually running and here we go now we can go ahead and save the program to see
what happens.
Now before we do let's go ahead and comment out.
This test case up above that one's going to fail by default.
So we'll go ahead and prevent that one from running for the moment and down below we can see what happens.
A few seconds pass and right here we can see that every single test case is a success which is fantastic.
That means just did go ahead and wait for these some following it.
It made the assertion and it called done.
Now if any of these were to fail the test case would fail.
So if I was expecting the number six.
Clearly that would be an issue and down below.
After a few seconds we would see the failed test case.
So I'll revert that bringing it back to its working state.
And we're going to explore one more way we could get this done.
So what we're going to do is use async await and to start we will call test and we'll provide a name
should add two numbers async await and then we'll provide our function to run.
This time though we're going to mark the function as a sync.
So what is this going to do.
Well yes it's going to allow us to use a weight inside of here.
But let's remember what we also know about async functions.
They always always return a promise when your test function returns a promise.
Gest is going to see that and it'll wait for the promise to either be fulfilled or rejected before figuring
out if the test case should be considered a success or a failure.
So what does that mean for us.
It means we can use a wait inside of here and just will actually wait till everything's done so we'll
get to go ahead and recreate the exact same test case up above using the alternative syntax.
So right here concept some equals whatever comes back from awaiting our call to add.
I'll go ahead and add up the number 10 with the number 22 for a total of 32.
And down below 0 we need to do is make our assertion I'm expecting the sum to be the number thirty two
if it is great.
If not we have a problem.
Right here I'll save the program to rerun the test cases down below we wait and all of the tests pass
which is fantastic and just approve.
This is actually working.
Let's go ahead and mess things up.
I'll switch 10 over to eleven that should cause our assertion to fail and I would expect to see a single
failing test right here.
It's running through the process and we do indeed have that failing test.
So when we're working with promises we can choose to either use done though this approach is a little
less common.
It's more common to use async await because of the benefits the syntax provides the same benefits we
get when using it in our program less nested callbacks and easier to read code.
So there's no challenge this video as I just wanted to go over a couple of basic concepts.
So here's where we're gonna go from here in the next lesson we're going to start the process of setting
up a test environment.
So if we are going to interact with our API we're gonna be reading and writing from the database and
we don't want to mess up our development database or our production database.
So we'll quickly set up a test environment with a test database and then we'll focus on testing the
Express application.
I'm excited to get to that.
So let's jump right in to the next lesson.