- Have a look at this example
in the mocking rest calls demo folder.
I've got a rest client
which is going to invoke a rest service,
a hypothetical rest service on my server.
So it's similar code to what we saw in the previous section,
but I'll just remind you,
there might end up some kind back end server,
a rest service at the back end.
And what I've implemented here is a rest client.
So I'm gonna draw that kind of here.
Here's my rest client.
And it provides an API.
It provides a method to get all products.
So there's my get all products function.
Okay.
And when I call that function,
it's going to use Axios to interact
with the rest service at the back end.
So I've imported the Axios library.
Let's imagine this is the URL of my rest service
over there on the back end.
So when I wanna get all products,
I say using my Axios library.
So imagine that Axios is kind of sitting here.
What we're gonna do in this section
is we're gonna basically mock the Axios layer itself.
Okay, we're gonna basically create a mock
of this layer here.
Okay, so that's the objective.
So in terms of that, Axios has got functions like get
and post
and put
and delete.
So I call the Axios get function.
I pass in the URL to get all products.
So my function here get all products,
it calls the get function there.
And what the get function does as you probably know
is it returns a promise.
So when I call the get function on Axios,
it returns immediately with a promise object
and that promise object will eventually contain the result
from the rest service eventually.
So when that result comes back eventually
and what actually comes back,
what you actually get back from the get function,
haven't talked about this before,
it's actually an object with the complete http response.
One property in there is data.
That's the actual result that you wanted to get back.
So in our case, that's probably gonna be a bunch of products
like that, okay?
But there are other properties as well in the response,
which kind of described the header, status code, headers,
and such like, and so on.
So this response that we get back from the get function,
this response here, which we eventually get back
when the promise is resolved,
that is the entire http response effectively.
What we then do is we say well,
actually I'm not interested in the entire response,
I'm just interested in the data part.
So we then extract the data part, okay?
And that data is basically what the user
is interested in getting back, okay?
Like the array of products.
Okay.
So how are we gonna, oh, and by the way
I've got another function here, get product by ID,
similar idea, get product by ID.
When I call that function for my code,
again it calls a get function
but with a particular ID appended to the URL.
So they'll send in a get request.
The response that gets back this time,
the data will just be one product, not all products.
So if you wanna have a look at all of that code for yourself
in the demo pack,
you go to mocking rest calls
and go into rest client dot JS, okay?
That's the code that I've just been through.
So what we're gonna look at now is how can I test
my rest API?
Well, how can I test it?
Because really it's a problem because it's gonna,
when I call this function for my test,
it's going to start doing Axios-related stuff.
So what I'm gonna do is I'm gonna,
in my test I will test that function,
but I'll mock the Axios get method or the Axios put method
or the a Axios delete method, okay?
So I'm going to mock Axios
and have pretend versions of those functions
that don't actually do a proper rest call.
So let's do that now.
All right.
So to mock the Axios model,
so first of all, in my test harness,
I input the Axios library
obviously because there were functions in there
like get and put and post and delete,
and I mock the entire Axio module.
So I've just created or rather jest has created
mock versions of Axios get, put, post, delete
and other functions that might exist in the Axios module.
I've got mock versions of all those functions.
And remember, when you mock a module each mock function
is kind of an empty implementation and it is is undefined
as a starting point.
Okay.
So let's press on, let's have a look at how to actually call
one of my rest functions mock in Axios.
So just a quick reminder of what we're trying to do
We had our, we had the Axios module at the back end.
Axios module had functions such as get,
okay, and post and put and delete.
I've mocked that function and by default,
that mock function would return undefined.
Okay, so I'm gonna mock it.
I've actually set up some sample data here.
Let's have a look at the full code
to see what that looks like.
So this is rest client.
So I've set up some ski-related products.
That's going to be my sample data for mock purposes.
So that's the sample data that we'll assume
is the starting point.
Okay, so that's there basically.
I'm going to mock the get all products method.
So in my rest client,
in my rest client
my rest client had a function
called get all products
and that's what I'm going to be testing,
get
all
products.
Okay.
So I'm gonna basically
my test is gonna be calling that function.
And as we know, when we call that function
in our code
that function will call ax get,
I need to mock that function.
Okay, so I mock the Axios get function.
When I think it's calling the Axios get function,
it's calling a mock version of that function.
And remember when you have a function that returns promise,
you can specify a mock return value not of the promise
but of the resolved result of that promise one step further.
So what I've done here, as I said,
imagine that the get function return to promise
and that promise succeeded
and the final result was this response object.
So I've actually mocked that function
so that the promise or the result of the promise
will be an object that looks like this.
Okay, so what have I actually specified here?
I've specified that the mock return value
is going to be an object
that has a data property
which is an array of products,
the skis and the goggles and the you know what,
plus any other properties that might be relevant.
Well, actually that that's all I've specified
in my mock response object.
The only bit I'm interested in is the data.
I don't want to mock the status code or the headers.
I just want to mock the response that I've kind of mocked
coming back from Axios contains that data
as if it had actually come back from rest service
but without actually haven't done that really,
I've mocked it.
Right, so when I call get all products,
okay, let's just think this through,
when I call get all products, it calls Axios get.
I've mocked that function, so that that function
resolves with the promise.
Okay, so,
there we go, in my test, call that function
that will return basically this data here,
that's the data that we've kind of mocked as the resolution
we said that that function resolves with the data
that I specified up here.
Mock verify that that data we've just got back
is the data that's been specified.
Okay, so verify that the data we got back
is equal to the products.
The data that we've got back is equal to the products.
Okay, so verify that this data here
was successfully returned.
And also if you want to be a hundred percent safe,
you can verify that the Axios get function
was actually invoked.
When I call that function, I can verify
that it did actually call the get function.
And I can verify that it called the get function
with this URL.
I'm checking that my function here get all products invoked
used the correct URL to talk to the rest service.
Did it actually use the correct URL when it said get?
That's worth checking because that's could be a bug,
you know, in the code.
Imagine in my code,
I'd actually had the the incorrect URL here.
Imagine I'd misspelled products as being like that, okay,
that would be a bug.
So I can check that when I call get all products
it does actually use the correct URL
in the get call.
When the get call was invoked, verify that it was invoked
with the correct URL.
Oh look, it wasn't, let's fix it.
There we go, now it is.
Okay, that's the first test.
So note in retrospectively,
we specify that the Axios get function should return
a promise which resolves with that response that object
an object that has a data property.
Good.
When we call the rest API,
it should call the mock version of get
which returns this mock result,
verify that it contains the right data
and verify that it actually called the get function
with the correct URL in the first place up there.
Okay, second test
is where I want to test the other function in my rest API,
'cause remember I have another function here
that returns one product.
So I'm gonna go through the same kind of process as before.
So here's my Axios module,
which I've mocked
and there's a get function
which I've mocked.
Here's my rest client, which I'm testing.
So this is my rest
client,
there you go in my best writing.
I'm now invoking on my rest client,
I'm invoking get product by ID.
Okay, so that's the second method really
get
product
by
ID
and a pass in ID one.
So well as we know, and we can check in the code actually
because I'm just kind of showing you the after effect,
when I call get product by ID,
it should call Axios get
with a URL such as example com API product slash one.
So I need to mock that function.
The last thing I want is for that to actually be invoked.
So let's mock that function, shall we?
Let's mock the Axios get function so that it resolves
with just one product.
It returns a response that has just one product.
Okay, so in other words, I'm mocking the get function
it will call the get function
and I'm mocking it so that it will return a promise.
And in that promise, it'll resolve with an object
and that object has a data property
which is one product, okay?
The resolved result is this response,
a data object with a data property, which is one product
as if it's come back from an actual rest service call.
Okay.
So let's verify that happened
when I call get product by ID with one,
what I get back here, is it the data that I get back,
is it the product one as expected?
It should be.
Oh, and also verify that the correct URL
was specified in the call.
When I call get product by ID, it'll call Axios get,
make sure that we called it with the correct parameter
with the correct URL, example com API products one.
Whatever parameters passed in there,
verify that it generated the correct URL
to send into the get request
there.
Okay, so there we go.
So just a note then,
I specify that the get function will resolve
with a result one product.
And then I make the call
and I verify that it gave me back the right result
and that it actually called the get function correctly
in the first place with that correct URL.
So I'm testing two aspects, really.
I'm testing the fact
that it did actually call the get function properly,
and I'm testing that it handled the result properly as well.
Okay, so.
That's it.
All we need to do now is run the tests.
Well, I've run them before and they work.
So there we are.
So what we've seen here then is we had a rest client
and the rest client was using Axios, okay,
and Axios is a low-level library
that actually does rest calls, and I've mocked that level.
So when I call my rest client and it calls into Axios,
I created a mock version of Axios
so that it doesn't actually issue real rest calls,
it has mock results instead
which allows me to test my rest API
as well as the rest of the code in my application.