In this lesson which is part to a continuation of the last one and you'll actually use jest to test
one of the Express end points.
Now there are two ways we could get this done.
One would be to actually start up the Express server on port three thousand.
We would then use an H TTP request library like the one we used with the weather application to make
real requests to our API from code.
Then we could make assertions about the response seeing if it's correct or not.
Well the Express team they actually released their own library that makes this even easier to do.
It's called Super Test and we're gonna go ahead and check it out in the browser install it and then
use it to over in the browser.
I've got a bunch of tabs open I'll go ahead and close a few.
I'm going to close.
Send grid my production database for the moment and over here in the new tab what I'm going to do is
Google the following NPM Super Test.
So the package we're looking for.
Super test should be the first result.
And once again this is a very popular library for testing especially when it comes to testing express
applications.
Now before we install this down below in the documentation I want to pull up a single example so we
can wrap our heads around what exactly we're trying to do.
So here is an entire example creating an express application and making a request to it asserting something
about the response.
So what do we do we load in both Super Test and express and then we define an express application and
set up a single route something we've already done.
So this is the stuff we already have in place.
We're not going to need to recreate this.
What we are going to do though is use these super test library loaded in up above to make a request
to the endpoint so we pass the Express application into request.
Then we chain on various methods to fire off the request attach images send Jason and assert things
about the response and we'll learn more about exactly how we can use it.
Once we start to use it.
So for now one key thing you'll notice is that a call to app not listen is nowhere.
But this still works super test.
Does it need your server to actually be up and running.
All it needs is the express application itself.
Even if it's not up and running and it can use that to fire off any of the requests that you're trying
to test.
So this is gonna be excellent for us when we're testing from just now that we can see what we're getting
ourselves into.
Let's go ahead and actually install this in our project and use it to make a request to one of our endpoints.
So over in package dot Jason.
I'll be shutting down the test command and I'll use NPM I to install Super Test at the latest version
which is three point four point one and we're gonna save this as a dev dependency using save Dev.
It's only something we're going to need on our local setup when we're running our test command.
Now once we have that installed we're actually going to be able to use it in our test file.
So right here it did get installed correctly.
I'm gonna go ahead and rerun NPM test and then we can actually take a moment to close down a few files
will no longer need package dock.
Jason is all set up so as test dot EMV and Dev dot EMV now in here what do we have.
We have our math dot and J.S. file and our math dot test dot J.S. file.
We're not going to use these for now but I will leave them in place just so we can remember exactly
how we did certain things though.
Now we're gonna focus on actually testing the task manager app so I'll create a more appropriately named
test suite alongside of the existing one over here in the test directory.
I'm going to create one called user dot test dot J S for testing the user related functionality for
our task manager app.
Now the first thing we need to do is load and super test so we'll start there.
Const request equals whatever comes back from requiring a super test.
Now you'll notice that these don't match up and once again this is just the convention that super test
uses.
You could call this whatever you wanted including something like Super Test but we'll go ahead and stick
with the variable name that they usually use.
The next thing we need to do is get access to our Express application but we don't want listen to be
called.
We just want the Express application before listen is called now for the moment and that's a problem
because the Express application is defined in this file we create it right here and then listen is called
down below.
So what we're going to do is perform a little bit of refactoring just restructuring things across two
files so we can get the Express application without necessarily actually calling.
Listen to do that all we're gonna do is create a separate file in the source directory so a new file
sitting right next to index dot J.
S and I'm going to call this app dot and J.
S This is where the Express application will get set up and exported.
Then our test suite can load it in an index dot in J S we'll also be able to load it in just so it can
call.
Listen let's go ahead and see what this is going to look like.
As it'll be easier to understand once it's done to start.
We're gonna take everything in index dot J.S. and copy it over to app dot J S now the only thing we
don't want to do an app dot J.S. is call listen.
So we'll remove it from there.
We'll go ahead and export the application so module right here dot exports and we're going to set that
equal to app now since we're no longer calling listen we're no longer using the port and we could go
ahead and remove that as well.
You could leave it in place but it's a bit unnecessary.
So this file sets up the Express application and exports the app.
Now we still want index dot J asked to work as expected but we don't want to have the same code in multiple
places.
These files are basically duplicates.
So what are we going to do.
Oh we're going to do is start this file off up top by loading in the Express application from app dot
J S so right here const app equals I'm going to require the file we just created that is dot forward
slash app and now we can remove almost everything in this file.
We can remove all of our required calls.
We can remove the line where we create the Express application and where we can figure it all we're
going to leave in place.
Are these three things we load in the Express app.
We define our port and then we call listen.
So when I want to start these server up in development mode what do I do.
I still just run index dot J ust it takes care of everything when I want to load in the Express application
strictly for testing purposes.
I just grab it from app dot J S and this is exactly what we wanted to do.
So we haven't changed the functionality at all.
We've just done a little restructuring allowing us to access that express application without necessarily
calling app dot.
Listen although when we need to write here we still do now over in the test file we can grab the app
so we can use it with super test cost app equals I'm gonna use require with the following path dot dot
to get out of the tests directory forward slash source forward slash app the file that we just defined.
Now with this in place will actually be able to make requests to our Express application from our test
cases and that is exactly what we're about to do right here.
I'm going to create the test case by calling that test function and providing a name for it.
I'll use something like should sign up a new user and this test case as the name suggests is going to
attempt to sign up a new user using post forward slash users.
Now I am going to mark this function as an async function as I'll be taking advantage of a weight down
below.
Now we're actually going to start by using a wait with super test as a super test supports promises
using a wait.
We'll make sure that the request actually finishes before jest figures out if it's a success or a failure.
Now how exactly do we use super test well we call the function we're provided request and we pass to
it our Express application.
So I'm going to call it passing an app.
Now the next thing we do is specify exactly what we're trying to request.
We have to provide the TTP method and the you are real and we do that by using a series of methods very
similar to those we used when actually creating the Express application.
So right here we could access get patch delete or post to make one of those requests.
In this case I want to use post but we'll explore the others later and we provide to it.
You are real now it's not the complete you are all just the path so forward slash users is exactly what
we had configured when defining our Express application.
Now from here we want to figure out how we can send data across the wire.
I want to provide real valid data and I want to expect that the user gets created and I get my 2 0 1
status code back.
To do that we changed on a method send send allows us to provide an object containing our data.
So on here we'll set up.
Name Email and password first up let's configure the name.
I'll go ahead and set it equal to Andrew.
Then down below that we'll go ahead and configure the e-mail.
Andrew an example.
Dot com.
And finally we'll set up a password.
And in this case we want all of the data to be valid.
We'll set up other test cases later with invalid data to make sure it fails.
For now though we want this one to pass.
So I'll use something like my password 7 7 7.
With an exclamation mark on the end.
Now from here we haven't made any assertions.
We've just sent things off to the endpoint.
We'll learn how to assert things about the response body a bit later to start let's just assert something
about the H TTP status code to do that.
We add on a another method call to super test that is expect we past to expect a number.
And in this case we're expecting a 2 0 1.
If things go well.
Now at this point I want to take things nice and slow because there's a specific problem with our setup
that won't be obvious at first.
So at first all we're going to do is save the file.
It's going to rerun all of our tests and we're going to see two passing test suites with seven passing
tests.
So this is fantastic.
It means that obviously our math tests are still working but it also means that our setup is correct.
We were able to load in just the Express application pass it to Super Test and make a request with this
data to the following endpoint and we got a 2 0 1 back.
Now we actually have data in that test database as well.
So if I had over to my Mongo D.B. compass application we can switch between the production database
and the local host database.
We'll be connecting to that local host database.
And now we have a task manager API test database alongside of our original one.
So this is the database that contains our test data.
And if I crack that open we have the one user created by our test cases.
Now what's the problem.
The problem is that if I rerun the test suite by either saving the file or just using a from just down
below this test case is gonna fail and it's failing because there's already a user with that email in
the database and this is gonna be a problem for us.
So when I mentioned earlier that we want to have separate databases for development and test this is
what I'm starting to talk about when our test case is run we need to make sure they're starting from
a nice clean slate.
So I actually want to wipe all of the data in the test database before the test cases execute to make
sure they can run consistently over time.
So it's up to us to set up a little bit of code to tell jest that it should be wiping data and setting
up specific data before the test cases run our test cases.
It shouldn't work once and then fail the second time because of what the previous run of the test case
did to the database that's going to create a test suite that's useless.
Every time our test suite runs the environment should be recreated and in our case that's as simple
as deleting everything in the database.
And as mentioned we'll also be setting up data in the database to start with later so we can test things
like the ability to log in or update a profile.
So let's go ahead and see what all of this is going to look like.
It'll make a lot more sense once we actually have it in place and that's coming up in the next lesson.
For now though we have a great start.
We do have a test case that is successfully able to interact with our Express application and make an
assertion about the response.
We'll talk about those lifecycle functions that just provides in the next lesson.
So let's jump right in.