- [Instructor] With this knowledge
about testing asynchronous callbacks in mind,
our application has a good candidate
for our callback unit test.
Within the schema is a validator
that uses an asynchronous callback
which returns an error and value.
The validate method does not interact with a service,
and it has a consistent signature and structure.
Therefore, it's a perfect place to start testing callbacks.
Let's write the validate callback test suite with Jest.
Switch to VS Code.
Go up to File, go to Open Recent,
and navigate to wherever your Nadia project is.
Before we write any code,
take a look at what we're going to test.
From the Explorer, choose lib, schema,
and choose reservation.js.
Scroll to the bottom.
The validate method takes a callback as an argument.
It then uses Joi, a validation library,
to check the structure of a validation.
I've destructured the output into separate variables
for the error and value.
After validation, I used setImmediate
to asynchronously return the callback,
which is slightly contrived,
but it makes for a good demonstration.
Let's write the test.
In the Explorer, select reservation.test.js.
Scroll to the end of the file.
Add a new line,
then start a new describe for the validate suite,
then use an arrow function expression with no arguments.
Why not done?
Because the tests themselves aren't asynchronous.
Our first test spec will be for valid reservations,
and we'll skip optional fields.
I'm going to add done as a callback.
So it should validate with no optional fields
and then done.
Now, here's a valid test reservation.
So const reservation equals new Reservation,
then we're going to pass it an object
with a date of 2017/06/10,
a time of 06:02 am,
party, size of four,
a name of family,
and an email of username@example.com,
then trailing semicolon,
add a new line,
then reservation.validate
takes one argument,
the callback which has an error and a value,
so error comma value,
then the arrow function expression.
We're going to wrap our asynchronous test in a try.
We expect the value .toEqual
the reservation.
When complete, return done, which we can pass the error to
in order to ensure that there aren't any validation errors.
After the try comes a catch for the error.
In this case, all we need to do
is to return done with the error.
That's all we need for the positive assertion.
Let's check the opposite direction, a negative one.
Add a semicolon and then a new line after the test,
it should validate with an invalid email,
and then add done as a callback.
Create a new constant for reservation instance.
We can copy and paste it from above to save time,
then edit the email to be just username,
which will fail validation.
Once again, we'll use the reservation instance to validate,
then the callback with just an error.
We won't bother to check the value.
We're going to try.
We expect the error,
and we're going to use a new matcher, toBeInstanceOf,
to check to see if it's an instance
of the class Error with a capital E.
Add a semicolon, and then return done when complete.
Notice that I'm not returning the error
because I knew it would exist already.
Let's wrap up with a catch error
where we will just return done with the error.
Add semicolons for consistency,
and save the file.
And we're all set.
Let's run our new tests from the terminal.
Open up the terminal.
Once it loads, type npm test, and press Enter.
Wait, why is there an error?
Let's see where this error is.
It's expecting error to be an instance of error,
but it got undefined?
Let's open up reservation.js.
Scroll down to the bottom to the validate method.
The only thing we changed was the email.
Oh, I see the problem.
Instead of validating an email, it's just checking to see
if it's a string of less than 255 characters.
Sometimes copy-and-paste programming is bad.
Edit the line to remove the max 255,
and then replace it with .email,
and then execute it.
Save the change, then switch back to the terminal.
Rerun the test, so npm test.
Much better, everything is passing.
We found and fixed a bug. Let's clean up.
Close up the terminal and any open editor windows.
That's how to test a callback.
So, how do we test promises in Jest?