- [Instructor] Mocking module dependencies can seem daunting
but the technique is really similar
to what we've already done.
As jest.mock manipulates the require cash
we can use jest.mock before requiring the target module
in order to alter module dependencies.
When ready then require the target module.
What's a practical use case?
Within reservations.js
this same function uses debug
to log a developer only message.
Then it uses connects to insert the reservation
into our database, which returns a promise.
For the purposes of testing,
I only care if debug was called
and that insert was called with a reservation.
In order to do that we're going to mock both debug
and knex prior to requiring reservations.js.
Previously, we relied on jest.mock
to completely replace the whole module.
This time we're going to use the factory argument
to override the default mocking.
Debug, once initialized with a label
is a function that we want to replace with a mock.
And knex provides an interface for building queries.
We're going to need to match this signature in our factory.
Switch over to VS code.
In the Explorer, open up reservations.test.js.
Scroll down under fetch and then describe a new group save.
So describe, save, than an arrow function expression,
same as before, we're going to let reservations
and we're going to require it momentarily.
However, this time we're going to create a mock debug
as a jest function that replicates
how the debug module works.
Const mock debug.
Note that the name starts with mock
otherwise jest will fail with a reference error.
So const mock debug equals jest.fn.
I'm also going to create a mock insert
and I'll use a new method mock resolved value
to match the signature of a successful insert,
and array containing jest inserted ID.
So const mock insert equals jest.fn.mockresolvedvalue,
singular and then an array containing the value of one.
Add a training semi-colon and then now for the mocking.
So V4 all and then arrow function expression,
jest.mock.
And then we're going to mock debug
which takes an arrow function for the factory
and then another arrow function for initialization
which then will return our mock debug.
That's what we'll be checking with our matcher,
add a trailing semi-colon.
And we're going to need two arrow functions
to mock knex as well.
So jest.ock and then we're going to use
the relative path to knex
which is the same as how it's used in the module.
Same as before an arrow function and then an arrow function
and then parentheses to return an object
with one property of insert,
which will have the value of mockinsert,
add a comma and then a semi-colon.
Finally we can require reservations.
So set reservations equal to require
and then the relative path of reservations.
Add a trailing semi-colon and then a trailing semi-colon.
Don't forget to clean up.
We'll use an after all error function expression,
we're going to use jest.unmark on debug,
then a new line and then jest.unmark
on the relative path to knex.
Add a trailing semi-colon
and we're all done with a setup.
Let's write the test spec itself.
It should resolve with the ID upon success.
And then an asynchronous operation.
So async arrow function expression,
our W value is just an object.
So const value equals an object.
We're not going to bother
with fully replicating a reservation here,
we just want it for comparison.
So Fu and that will set it the value to bar,
trailing semi-colon,
and then we'll also expect the return value to be one.
So const expected equals an array
containing the value of one.
Now for the actual execution,
set const actual equals await reservations.save
with the value.
Now for the assertions,
I expect the actual value to strictly equal the expected.
This is going to be a new matcher.
So .twostrict equal the expected.
I also expect that the mock debug was only called once.
So I'll use the matcher to be called times one.
Finally, I expect that mock insert
was called with the original value.
so.tobecalled with, which is a new matcher,
and then value.
Add trailing semi-colons,
save the file, then switch over to the terminal.
Run the test.
Fantastic.
Everything passed.
Let's clean up.
Close out the terminal and close the test file.
We've used mock functions in mocked entire modules
but is there a more nuanced way
of mocking just part of a module
without automatically mocking the entire thing?