Now of course there is more we could test on our off middleware but I'd say we tested it quite extensively
thus far and therefore I want to move on and I want to move on to our controllers which of course also
house a lot of our core logic.
There we have that off controller.
Obviously we have that feed controller now for that feed controller.
We have routes where we need to be authenticated.
We have a look at our routes here for getting posts.
For example we need to be authenticated for creating posts.
We need to be authenticated essentially for all our post related rulings.
We need to be authenticated and before we take care about that let's have a look at our off controller.
Therefore because these routes don't require us to be authenticated though does it really matter too
much as to question.
Well let's have a look at how we reach our controller functions here like sign up or log in.
We of course reached them through our routes which are defined in the routes folder where we send requests
to India.
So these are the API and points we're exposing here.
And now what did I mentioned earlier.
What what are we testing.
Well we are writing units tests.
We are testing units in our code just as the middleware do you off middleware.
And therefore what will not test is the routing here will not test whether we can send a request to
log in and we execute the log in function in the off controller because that entire for warding off
the request the execution of this method here.
That is all handled by express.
And as I mentioned earlier you don't want to test our libraries.
You want to test your own code.
So we absolutely don't need to test this flow and therefore we'll just test these controller functions
we export here like the sign up or to log in function.
These are the things we want to test now when they're there of course again is a broad variety of things
we can test.
We can test whether we're able to extract e-mail and password from the incoming request though that's
a test that's not too useful because we will simulate the request that's coming in.
So we decide whether that is set or not but we can then test if it behaves correctly if no e-mail is
set for example or if we already have a user with that e-mail.
However there is one new complexity added.
Now we have a database now we're interacting with the User model here and the User model of course is
based on our Mongoose models here.
That's our user model and that behind the scenes uses Mongo D.B. and that of course brings one important
question to the focus how can we test our database.
How can we handle this now.
And turns out there are two main strategies we can follow.
So let's have a look at both strategy number one for testing code that involves database operations
is that we stub or mock the parts that actually rely on database access and what would this mean.
This could mean for example that here when we execute find one we again create a step that returns a
predefined result and we then test if our code behaves correctly.
So for example we might be interested here in finding out how our code behaves when find one frozen
error.
So if we're having trouble interacting with the database or how our code behaves if we don't have a
user with that e-mail address when logging in.
These are two different scenarios and we can write two different tests for that.
Both scenarios should actually throw an error eventually.
Here we throw one manually and if find one fails it also will throw an error but the status code for
example should be different.
The status code should be 500 if the database fails because we use our default code then or we set our
own 401 code.
If we have no user now to test us all first of all create a new file in the test folder and I will named
as of controller dot J.S. and in there just as in the off middleware file I'll import expect from China
and I'll also import sign then because I will start with stubbing that post to find one method that
of course add that user find one method therefore I will also import the user by requiring it from the
user model file just as I'm doing it here in the off controller there we are also importing the user
model.
So now I want to test and log in function and since I want to test that function we need to import this
year as well or in general I'll import my off controller by requiring it from the off file and the controllers
folder.
Now let's add of the scribe block maybe where we test our off controller log in process because even
if we're only testing the off controller in this entire file we might be testing different parts of
that controller like log in and sign up and so on.
So you're old start with log in and then here I want to start by stopping my find one method because
that's the first tactic we can apply we can simply stop that a ways that we don't make a real database
access.
So here what we can do is of course I can again use sign and create a stub create that on the user object
for to find one method
now if I want to you forced us to throw an error.
I can then call the user find one throats now here does will throw an error now by the way.
Of course one issue I have here is that I'm into the scribe blog.
This should go into an IT block that was so into an actual test case.
So here it should flow an hour or if accessing the database fails.
For example.
So now here in that function we define our actual test code and there we set up that stub.
And the important thing here of course is I'm faking that data base fail because I completely replace
to find one method with a stop that will throw an error because the actual thing I wanna check is of
course that we should throw an error with code 500.
So I want to check whether our default status code down there really gets applied correctly.
Now back in the off controller in the end I also want to call restore here.
But in between I of course want to define my expectation and the expectation here is that for my off
controller the log in method when that gets called that it actually throws an error.
Now for that let's have a look at the off controller again and you should now recognize that we have
to async keyword in front of that.
It's not a normal function it's an async function and that means in the end we use promises in there.
You might remember async await is just a more elegant syntax for using promises.
So actually we have a synchronous code in here which is a navigate complexity will have to deal with
because the execution of that code will not happen synchronous.
And that means that by default our expectation you won't work the way you might expect it to work.