(upbeat music)
- [Narrator] Here's the solution to the challenge
about isolating express routes
for faster functional tests.
If you haven't completed it yet
please take a moment to practice your skills.
This solution is going to involve some restructuring
including renaming existing files,
updating functional test setups,
and creating a separate file.
Within the exercise files,
the progress 05_09 end folder,
will contain the end result.
What needs to be done for this refactoring?
First we'll create a standalone router
that includes our custom routes named index.js.
However, that collides where their existing
index.js router for the homepage.
So, we'll need to rename it to homepage.js
and update the associated test.
With that out of the way,
we can now create a new minimal express router.
We'll also update the other routers to include the base URL
which is currently set in app.js.
With a freshly configured routers,
we'll update app.js to use the unified router
instead of the individuals.
We'll also need to update each of the functional test files
to mock the router
and include only the route that we want to test.
This may sound daunting,
but honestly we're going to touch about
two dozen lines of code.
Let's get started.
Switch over to VS Code.
The first thing we need to do,
is rename our homepage router.
In the Explorer, click Routes,
and then right click on index.js,
and select Rename.
Rename the file to homepage.js.
If prompted to update the imports for our homepage.js,
do so.
We'll also need to rename the test.
Right click on index.test.js
and go to Rename
I'm going to rename the file to homepage.test.js.
Now that we've cleared room for our unified router,
let's create it.
Right click on Routes
and go to New File.
The name is index.js.
We're going to start by including express.
So const express equals require express.
Then we're going to initialize the express router.
So const router equals express.router
and execute it.
The next thing we're going to do,
is use the router.use to require
the homepage.
We'll do the same for router.use require
the admin page,
and finally router.use require
the reservations.
At the end assign module.exports to the router.
Save the file, then close it.
Right.
What's next?
Updating each router.
Open up admin.js.
Just a quick change here.
On line eight,
the router should just be /admin.
Save the file and then close it as well.
We don't have to change the homepage
as it's just the route
but reservations.js should be updated.
Update line seven to be /reservations
and then do the same on line 11.
Save the file, then close it.
Let's update the app itself.
If it isn't already,
open up app.js in the route.
Scroll up and remove the existing routes
and replace it with const routes equals require
than the relative path to routes.
And that's it.
Now we're going to scroll down
and we're going to remove these broken routes.
And then just after the auth admin,
use the new routes.
So app.use routes.
Add a trailing semi-colon
save the file and close it.
Now that we've updated app.js
we can update it's associated test.
Open app.test.js.
In the before all,
add a new line and then use just.mock
on the relative path of routes.
And we're going to mock routes with a middleware
that does req, res and next
and it just does nothing.
So just execute next.
Add a semi-colon.
In the after all,
remember to unmark routes.
So we don't inadvertently impact other tests.
So, just to unmark routes.
Add a trailing semicolon and save the file.
We're almost done.
We just have to update the individual route tests.
Let's close this and start with routes admin.test.js.
In the before all,
we're going to start off with a just.mock for the module./
which is the shorthand for the index.js router
in the same directory.
It requires a function for the implementation
which we'll just use to require admin.
Remember to clean up in the after all.
So, just.unmark
and then ./.
Add a trailing semi-colon and save the file.
You can close this file
and then open up homepage.test.js
We're going to do something very similar to admin.
In the before all,
we're going to use just.mock
and then relative path to the index,
and then when executed it'll just require homepage.
Then in the after all let's do the cleanup.
just.unmark
and then the relative index.
Add a trailing semi-colon and save the file.
Let's close this down
and then open up reservations.test.js.
Scroll up to the top.
This should feel familiar.
In the before all,
add just.mock to the index,
then function expression require reservations.
Trailing semi-colon.
And then in the after all,
just.unmark the index.
Add a trailing semi-colon and save the changes
and then close all open files
Ready to give it a try?
Let's do a quick sanity check first
to make sure that the service itself
is still running properly.
Open up the terminal,
then run the application.
npm run start.
From the browser, navigate to local host port 3000.
Great.
The homepage is still there.
Click on Reservations.
It works as well.
What about /admin?
The username and password are admin
and it works.
Hooray for a non-user impacting refactoring.
Close the browser.
Back in the terminal,
press CTRL+C to terminate the batch job.
Say yes to the prompt.
Let's run the newly optimized tests.
Use npm test -- --verbose
to see the timing.
Before we do that,
let's maximize the window so we can see everything
press Enter to see the result.
We still have 100% test coverage.
Was it faster?
Let's look at the individual tests.
These timings for the functional tests
are definitely faster.
But as the overall time reported
it can be a little variable
due in part to additional setup and tear down.
So was this exercise worth it?
In a smaller existing application,
it might not be worth the effort
if it's already structured like this.
Locally, when I was benchmarking this,
I saved roughly about a half to a full second.
Unnecessary micro optimizations
can waste valuable development time.
Now, what if this was a much larger
or more complex application?
Absolutely worth it.
It can save minutes or even hours
depending on the scale of the application.
At the end of the day,
I feel it's a best practice to structure applications
so they can be tested in isolation
especially if you're building something new.
Thanks for following along.
These challenges were fun for me
to design and implement
and I hope you had fun too.