Testing ExpressJS REST API with Mocha and Chai

Parth Joshi
Kanssfer Consulting
6 min readSep 14, 2018
Photo by Wes Hicks on Unsplash

ExpressJS is the most famous Node.js framework for creating Web Applications and REST API or so-called Micro Services. It provides a default MVC flavor along with “Micro-Service” flavor into a single package. It would be a bold statement, but I believe lots of frameworks have inspired from the intuitive and route-mapped callback driven Micro-Services in ExpressJS.

Lots of GUI based tools are used to test the REST APIs, Postman is one of the famous ones. But I feel and I strongly recommend that instead of using Postman, developers should develop a practice to test the API using Unit Testing Frameworks like Mocha and Chai.

In this article, we will quickly write a skeletal for Books API and perform CRUD Operations on Books Collection. We will use Chai and Mocha to test the REST API and also perform test automation along the way.

Before you Start

This article assumes that you know the basics of Node.js and Express.js. You should consider to download Node.js and Express.JS and install it on your machine and try some code before you try the stuff in this article.

If you are new to Express.JS then you should consider learning ExpressJS first. Take a look at this tutorial for learning the basics of Express.JS.

Getting Started

Lets create an Express.JS application using Express Generator Tool.

$ express rest-api

This will do the scaffolding for your Express project structure. If you know basics of express and have used express generator tool before, you know the drill.

$ cd rest-api && npm install

And then open the code in your favorite IDE.

The Books API

In this article, we will create Books API. We will perform CRUD operation for the for the Books Entity for a NoSQL DB.

To keep things simple let us consider only 4 fields for the Books Entity(in JSON) :

  1. ISBN
  2. Name
  3. Author
  4. Year (of publication)

A Sample JSON Value:

{            
"isbn": "121212",
"title": "World Is Best",
"author": "Larry",
"year": "2016"
}

We will take up following CRUD Operations:

  1. Create Book
  2. Read Book (By ISBN)
  3. Read all Book
  4. Update Book (By ISBN)
  5. Delete Book (By ISBN)
  6. Delete All Books

I have a practice of creating [which every Ex-Java developer might have a practice of 😀] a Dao Class which will take care of the CRUD Functions. So before declaring the DAO, let’s write a global DB object in app.js, which we will pass in each function call to our Dao Functions.

Setting Up Mongo Driver for Node.js

We will be using MongoDB as noSQL in this Article. I am assuming that you have a version of MongoDB Community Edition installed on your machine and have some knowledge of noSQL and MongoDB Commands.

Installing MongoDB Driver for Node.JS

The simplest driver is “mongodb” npm module. To install it fire following on your Express Project Home Folder.

$ npm install mongodb

Setting Up Global DB Object

Let’s set up an application level object which will hold the DB Connection, which we will use in the DAO function calls. Add following snippets on your app.js file.

Make sure you have an instance of mongod running on your machine when you execute this application and have a testdb database created (or any db name of your choice).

Creating DAO

As discussed earlier, we will take up following CRUD Operations:

  1. Create Book
  2. Read Book (By ISBN)
  3. Read all Book
  4. Update Book (By ISBN)
  5. Delete Book (By ISBN)
  6. Delete All Books

Create a file in dao/BooksDao.js in your express project and add following snippets in the file:

You can see that there are six functions for six CRUD operations we discussed. Now let's write code for one function to insert the book in the DB. It will have two arguments:

  1. Database instance
  2. Book Info

The above code uses promise to have an async function call. The code used Q library to have a “promise” mechanism. I suggest referring to promises and Q module if you are already not aware of the same.

If the insert is successful the promise will be resolved and status JSON will be returned to the routes, which can be analyzed and sent back in the response to the client. In case the insert was not successful, promise will be rejected and error will be handled in the caller function in wait state.

Let’s see the entire DAO with functionalities of all size CRUD operations:

Looking at the first function, the rest of the functions are quite intuitive.

Setting up the Route Middleware

Now we will have to wire the Books route middleware with the CRUD Operations. For those who know how RESTFul services work, its simple to map HTTP Methods with CRUD Operations:

  1. CREATE — POST
  2. READ — GET
  3. UPDATE — PUT
  4. DELETE — DELETE

Let’s see a code for Create operation (post method) and the rest of the functions will be intuitive from the same:

The BooksDao is called in this route handler file and we have called respective promise handling for success and error cases and mapping it with respective response to the client.

Now let’s see the complete code to digest what’s happening with the route handler:

Next step it to register the middleware to the app.use function, and we will do it in app.js which we see in next section.

Registering Middleware in App.js

Like all other routes, let's register our middleware module for /books path:

Getting Started with Mocha and Chai

We will be installing the following modules of Mocha and chai:

  1. Mocha
  2. Chai
  3. Chai HTTP

To install the dependencies, you can fire the following command:

$ npm install mocha chai chai-http 

Mocha and chai are very famous Unit Testing Frameworks for automated testing. We will be using chai-http module to make HTTP Requests.

Creating a Test

Create a file test.js in the test folder of your express application folder:

We will be using some functions of Mocha and Chai framework for performing this tests:

  1. describe(): used to club multiple tests in one collection.
  2. it(): a single test unit, mentioning how it should behave and a callback to execute the test body.
  3. chai.request(): to make an HTTP Request to the REST API
  4. done(): metioning the test was successful.
  5. xx.should.xxx(): should is a great feature in chai library, helping us to assert the test condition. If the condition fails, the test fails. In simpler terms it’s sophisticated was to make test assertions.

Let's see a single test for deleting all the books:

To add the books:

To Fetch all the Books

Let’s add a test to fetch all the books:

To Fetch a particular Book

Let’s add a test to fetch all a particular book. We can add an ISBN statically in the route parameter:

To Update a Particular Book

Updating the book and testing whether the update was successful:

To Delete Book

Let’s write a test to delete a book, and then test to see whether delete was successful:

Putting it all together

Let’s see the complete collections of test just created:

Run the Test

Let’s add a test script in package.json :

..."scripts": {
"start": "node ./bin/www",
"test":"mocha"
},
....

To run the test, try the following:

$ npm test

The unit tests will be executed, calling the API and giving you the test result for your code.

Final Thoughts

I feel and I strongly recommend that instead of using GUI Tools, developers should develop a practice to test the API using Unit Testing Frameworks like Mocha and Chai. This will create a habit of unit testing and also enable us to create a template for automated tests in the future. This gives a comprehensive test environment than the ones in GUI Tools.

About the Author

Parth is a Trainer, Consultant, and Entrepreneur. He is also an author of the course “Learning Express.JS: Building Future Web Applications and API ”. His is passionate about training and have trained employees of multinational companies for topics like Java, Java EE, JS Frameworks and Python. He is a child prodigy in coding. His consulting firm takes up projects Regarding Open Source ERP Implementations, Blockchain, and IOT.

--

--

Parth Joshi
Kanssfer Consulting

Togaf 9.2 Certified, Solution and Enterprise Architect, Consultant and Trainer