This exercise will walk you through writing a small Node.js application and writing unit tests for it. You will learn how to:
- structure your code to separate concerns effectively, which maximizes readability, maintainability, and testability
- write small, focused tests for your application-specific logic
- use a technique known as "dependency injection" to simulate interaction with a remote service
- write an automated integration test for your application
This exercise assumes you are comfortable executing commands in a UNIX environment. Specifically, it expects that you are familiar with the basics of how to create directories and files on the command line of a terminal program.
Docker users: Ensure you have docker
and docker-machine
installed. Run
./docker-startup.sh
to build and run the docker image and open your web
browser to appropriate web address. You may have to refresh after the server
finally starts.
OS X users: Consider using Homebrew to install the software described below.
-
Install Node.js on your system. This package requires version 4.2 or greater or version 5 or greater. You may wish to first install a version manager such as nvm to manage and install different Node.js versions.
-
Install Ruby version 2.2.3 or greater on your system. You can see if it is already installed by running
ruby -v
in a terminal window. You may wish to first install a version manager such as rbenv to manage and install different Ruby versions.Why Ruby? The
./go
script mentioned below is written in Ruby. The content is published and hosted locally using Jekyll, a Ruby application. -
Install git if you do not have it installed already.
-
Clone this repository and change into the working directory by running:
$ git clone https://github.com/mbland/unit-testing-node.git $ cd unit-testing-node
-
Run
./go serve
to serve the site locally.The
./go
script will check that your Ruby version is supported, install the Bundler gem if it is not yet installed, install all the gems needed by the exercise website, and launch a running instance onhttp://localhost:4000/
. -
Visit http://localhost:4000/ in your browser.
Run all the installation instructions to make sure the site builds. Then, in your clone of this repository, run the following to ensure your installation is in a good state:
$ npm install
$ ./go ci_build
The directory layout is as follows (note that in this exercise, content in the directories other than pages
pertains to the code used in the exercise):
-
pages
: contains the content of the exercise website -
exercise
: contains the content that the person following the exercise will edit -
.exercise-init
: contains the content used to create the starting state of the exerciseNote: The
exercise
and.exercise-init
directories should always remain identical in the published version of the repo. -
solutions
: contains subdirectories containing solution content pertaining to chapters of the exercise00-CHAPTER
: each chapter should have a corresponding directory containing the solution content for that chapter, with a unique numeric prefix reflecting the order of the chapterscomplete
: this directory should contain the solution content reflecting the completed exercise
Each 00-CHAPTER
directory need not contain the full content from previous
chapters; only the content that has changed relative to previous chapters.
This is due to the way that the ./go
commands to set exercise
state work,
discussed in the next section. However, each chapter should be self-contained
and testable in isolation from other chapters.
The solutions
chapter from this exercise contains:
00-config
01-rule
02-slack-client
03-github-client
04-log
05-middleware
06-integration
complete
The ./go
script will create the following Tutorial commands
to set
the state of the exercise
directory:
start-over
: sets the state to the very beginning of the exerciseset-CHAPTER
: sets the state to that required at the beginning ofCHAPTER
, whereCHAPTER
corresponds to one of theOO-CHAPTER
subdirectories within thesolutions
directoryset-complete
: sets the state to that of the completed exercise
The Tutorial commmands
from this exercise are:
Tutorial commands
start-over Restore the initial state of the exercise files
set-config Set up the files for the config chapter
set-rule Set up the files for the rule chapter
set-slack-client Set up the files for the slack-client chapter
set-github-client Set up the files for the github-client chapter
set-log Set up the files for the log chapter
set-middleware Set up the files for the middleware chapter
set-integration Set up the files for the integration chapter
set-complete Copy the complete solution into the exercise dir
All of the ./go
commands that update exercise
state start by clearing out
the exercise
directory and copying over the files from .exercise-init
.
Every set-CHAPTER
command will then copy the files from each previous
solutions/00-CHAPTER
directory into exercise
, one directory at a time.
Since each 00-CHAPTER
directory need only contain partial content, this
process will build the complete state required at the beginning of the
target exercise chapter.
(Note: This presumes that content files will not be removed during the course of the exercise; may want to revisit this mechanism in the future.)
The ./go set-complete
command will reset the exercise
state to the
beginning before copying over all the files from solutions/complete
.
All of the scripts
in the package.json
file are
implemented via gulpfile.js
:
- The
npm test
andnpm run lint
commands only operate on the files in theexercise
directory. - The
npm run test-all
command processes.exercise-init
and allsolutions
subdirectories, in serial npm run lint-all
command processes every.js
file in the project
The buildArgs()
function in gulpfile.js
enables the following npm test
syntax to allow running a subset of tests matching a regular expression:
$ npm test -- --grep '^Config '
Alternatively, if you want to use gulp directly:
$ npm install -g gulp
$ gulp test --grep '^Config '
$ gulp test-all --grep '^Config '
This project uses ESLint for static analysis. See the ESLint configuration
user guide and ESLint rules guide for details on
each parameter of the .eslintrc
file.
This software is made available as Open Source software under the ISC License. For the text of the license, see the LICENSE file.
This is derived from the original 18F/unit-testing-node implementation.