- [Speaker 1] It's time to start writing unit tests.
But what are we going to test?
We have a few candidates in the application.
The reservation application has a number of custom scripts.
App.js is the express application itself.
It's less custom code and more of a configuration.
The server is located in bin/wwww.js
and sets up the HTTP listener.
The library directory contains the schema for a reservation
which is really standalone.
It also has reservations logic
and configuration for basic auth.
Finally, there are three routes for the admin interface
which shows reservations, the static homepage
and the reservation form.
These are very thin routes, which delegate the work
to other libraries.
So they're mostly just configuration
and a little bit error handling.
Out of these, this schema is the best place to start
with a unit test.
Let's take a look at the file itself.
In VS code in the Explorer,
open up lib, schema, reservation.
It's a lightweight class with only three methods
but it's very useful.
First is the constructor, which creates a reservation.
The constructor just copies with the exception of the call
to combine date and time.
Combine date and time is a helper that combines the form
submitted date and time into a standard ISO date time.
Finally, there's validator, which executes
a third-party validator against the instants properties
and returns the result.
Out of those, our first unit test candidate
is the method combine date time.
It's atomic and completely standalone.
It does not interact with any service like a database.
Finally, it has a consistent signature and structure.
It doesn't hurt that it's one line long
and has an example in the documentation.
So why should we start with combine date time
and not the others?
The constructor makes a call
to the combine date time method
so it's not completely standalone.
What about the validator?
Well, since it's testing the instants,
the constructor must be called first.
They both can still be unit tested
but it's best to start as atomically as possible.
We know what we want to test.
So where do we put the test file?
There are two common locations.
The first is a separate test directory
and the other is the same directory.
Let's compare the two approaches.
Separate test directories typically mirror
the folder structure of the application.
This makes it easy to structure the tests
and have a nice clean separation
between what is being tested and the tests themselves.
However, creating folders can be a bit repetitive
and there's no practical way to keep the folders in sync
if you rename something
For example, a file location in the lib schema
would have a corresponding tests/unitversion.
Note that I'm including the type of test
to make it explicit, which is helpful
when there are multiple kinds of tests in a project.
The alternative is keeping the tests in the same directory
where the source and test files are in the same place.
The primary advantage is that everything is always
in sync and in the same place.
However, this can lead to larger numbers of files
in the same directory and tedious file naming or renaming.
For example, lib schema reservation would have
a corresponding libschemareservation.test.js.
Both approaches are valid and are supported by
Jest and I've used both.
Keeping unit tests in the same directory
as the files they're testing is convenient.
So our core standard will be to put the unit tests
in the same folder.
Test themselves should also have some organization.
When using jest and other frameworks,
test specifications should be structured
inside a suite of tests.
Jest provides a function Describe
which provides support for scoping tests.
Describe is common across many frameworks.
Describe supports nesting,
which allows a suite within a suite.
With that said, Jest puts tests in an implicit suite,
the file itself, so there's no need to wrap everything
in a suite that defines the file.
For example, we don't need to describe
the reservation schema,
but Describe for the suite for the validator is logical.
Let's apply this knowledge practically
and write some unit tests.