Welcome to Part 2 of this review of the Pluralsight course Node.js Testing Strategies by Rob Conery
Rob has been working in the technology field full time since 1998 as a DBA and then a web developer. His original focus was the Microsoft ASP.NET stack, building tools like Subsonic and the first Micro-ORM: Massive.
He co-founded the online training site Tekpub.com with James Avery and co-host This Developer’s Life with Scott Hanselman.
Tekpub was bought out by Pluralsight and he worked there for two years. He is currently working on a new book called The Imposters Handbook.
Also in this series:
Part 1 – Introduction
Part 2 – Simple Tests with Node.js and Mocha
Part 3 – Data Access Considerations
Part 4 – External APIs
Simple Tests with Node.js and Mocha
The Membership Application
We revisit the first test we wrote in the last module.
What we want to do is work out our specification and describe it. We’re not concerned with the solutions at this point.
Applying to mars is our feature.
Using valid email, first, last, height, age weight is our scenario.
When a user applies to fly to Mars using all the valid details, our code must ensure that it:
- is valid
- reports a valid email
- reports a valid height
- reports valid age
- reports valid weight
- reports valid name
These are our behaviors.
Next we see Rob write the code and explain the reasoning behind it.
Rob likes to follow the Tell, Don’t Ask principle and spends a couple of minutes explaining this.
He decides to use underscore, and the extend method which allows the code to be simplified.
Rob isn’t at all dogmatic about red-green-refactor so we see a different testing style in this course.
He says the focus of this course will be about the tools and how to use them in Node.
The Membership Application, Part 2
We see the Mocha before block, where we create a validApp object.
Then we write each of our tests, and the goal is to keep things as simple and clear as possible throughout this project.
When we have 6 passing tests, we rewrite the test names to read better. The tests become much more descriptive, for example:
“email is 4 or more chars and contains an @”
I have found this approach is more helpful for other developers reading the code.
Some of the BDD philosophy is that the tests can be read by business users. This remains the case here but they are describing the functionality at a lower level than business users tend to think at. For example, a business user might say “email is valid” and not consider what that means specifically.
For the developers, this must be considered and writing the tests in this way makes it clear to other developers reading your code which decisions have been taken.
All of these tests are as simple as they could possibly be.
We also see the doc mocha reporter, which outputs to HTML.
The Sad Path
Our scenario is now “Application invalid if…” and we see how to write these tests:
- email is 4 characters or less
- email does not contain an @
There are a lot of other tests as well, but because they all follow the same pattern, there’s no need to see all of these being written.
A really strong point that Rob makes at the end of this lesson is:
“No code is the best code and that includes tests”
Every line of code that you write should be able to justify it’s own existence.
Testing Dates with Moment
We see the skip keyword being used and learn when and why we might want to use it
We also see Mocha’s only keyword in use, and see how to resolve moment issue 1407:
“moment construction falls back to js Date. This is discouraged and will be removed in upcoming major release.”
Testing Process Behaviors
We see how to use Node’s EventEmitter, and write a validationMessage function that will simplify our tests.
We write a findNextMission function.
Then a few functions are stubbed out until we have a better idea of how to implement them. This is all part of the design process.
If any of our methods fail, it will trigger the invalid event, passing in an error message.
We now have a set of functions without tests, so we write specs for this code. This time we mark the tests as asynchronous.
To install Sinon:
npm install sinon –save-dev
Rob shows that it is easy to create a spy with sinon. If you have ever used Jasmine Spies before you’ll know that the idea here is basically the same.
We see that there are problems with sinon and events. We have a have a process that is calling a function directly, not the result of an event trigger.
We end up creating four different sinon spies in this example, and we also see how to use callCount.
The code we’ve written was a good effort, but it isn’t the best. It’s lengthy an inelegant.
Rob checks the current into git and checks out a new branch. Now let’s install Caolan McMahon’s async library:
npm install async –save
Rob provides an overview of this popular library. It has been in development for over 6 years now and 177 different people have contributed to this awesome project.
You can find all of the documentation here.
When have several function that each take an app parameter. Rob updates these to next and this is a callback.
We no longer need our process endpoints, or the event chaining, so we see our code getting a lot slimmer.
Rob demonstrates async.series, which executes a number of functions one after the other.
We skip some test. Once all the remaining tests are passing, we setup our spy the way it should be: spying on each function of the review function.
We can now remove the skips and see that all tests pass.
We are using async in a brute force way by passing in an array of functions. Rob shows us how to name these functions by passing in an object.
The async library looks awesome, but it’s a big topic. I’d love to see a whole course dedicated to using it deep dive style.