Testing RESTful APIs Using Mocha, Chai and Chai-Http Plugin

Oboite Osahon
5 min readMar 13, 2019

--

Despite my knowledge, however little, of writing unit tests, the thought of testing APIs was nothing less than frightening. For whatever reason, I just could not wrap my head around testing APIs. “How is it even possible…will it run on a separate server?” I thought to myself. Although I knew I would get an answer from Google, I was quite scared about what I’d find. I assumed it would be something super complicated, and I didn’t understand why I should write tests for my APIs instead of using Postman at the time.

Fast forward to last week, I had to write tests for APIs. This was not up for debate, so I had no choice but to look it up. There were different options for testing APIs, just like every other package on npm. Being familiar with ChaiJs, I chose Chai-Http without thinking twice.

It turns out that testing REST APIs is not as hard as I thought I would be. Didn’t Nelson Mandela rightly say “It always seems impossible until it is done.”?

Enough talk, let’s write some code!

I want to show you an example of how to test a REST API using Chai-HTTP. Believe me, it’s not as hard as it may appear.

Clone/download the application we will be writing tests for from GitHub, here. I don’t want to bloat out this post.

After you have cloned this repo, and have NodeJs installed on your local machine, navigate to the folder using your command line and run `npm install` to install all the dependencies.

If you want a walkthrough, hit the subscribe button so you will get notified when I make the post.

Your cloned folder structure should look like this:

In your test/index.js file, add the following code:

A rundown on what we are doing:

  • we imported chai and chai-http
  • next, we imported our express app instance. So instead of writing out complete url localhost:3000 every time, we could just request the app
  • we then want to use the expect assertion style from Chai. Check out the different assertion style chai has here.
  • chai.use(chaiHttp) tells chai to use the specified plugin. This is how chai uses every of its plugin.
  • Then we “describe” what we will be testing. Think of it as a way of grouping tests. This describe function takes a callback, which in turn takes an…
  • ‘it’ function. This is the actual test case. Think of the ‘it’ callback function as the green mark bearer — you will see that soon.
  • You can see “done” being passed as a parameter in the callback function of “it.” This is a way to tell Mocha that we are running an asynchronous code, so it doesn’t get ahead of itself.
  • Then you can see the bad-boy at work — chai.request(app) This makes a call to our app. It tests the response gotten from the app to see if it matches with the assertions.

Now is the time to make those assertions. Below the .get() we are going to chain one more function: .end()

This end function takes two parameters: err (error) and res (response).

If an error occurs, we will call done(err) and let Mocha worry about that.

If a response is gotten, however, we then test to see if it is returning our desired response object. Here we want the following conditions to be met:

  1. res must have an HTTP status of 200.
  2. res must be an object.
  3. res.body.status must equal ‘success’
  4. res.body.movies must be an array.

To run our test, we need to add a “test” script to our package.json file like so:

We are using babel to compile our ES6 to ES5 code because Mocha does not allow arrow function. You can find out more here

Now it’s time to run our test

Oh No!! It failed.

You should see something like this:

It had to fail because we have not written any code for the API. So let’s do that now.

For the sake of doing things properly, we are going to add a controllers.js inside our server folder.

In this file, add the following code:

PS: I am using export default because there is only one function here. You wouldn’t want to do this when you have multiple functions. Check out the finished code example here (link coming soon) to see how this ought to be done — at least, in my opinion.

Now, we have to make use of this controller. In your routes.js file, add the following code:

We are making use of the express router. What we’re saying here is when a client reaches localhost:3000/movies we want the getAllMovies function to run. Leave a comment if you have a question about this or checkout out express routing documentation.

Our route has been set, now we have to import it in our app.js file and configure body-parser

In your app.js file, add the following code:

Our application is set. Our test should pass now. If you run npm test now, the test should pass.

Awesome!!

The good thing with ChaiHttp is that it gives us some sort of guide while building our APIs. By writing tests first, our responses will be more consistent — response messages and HTTP status codes will match the one in the test files.

I hope you love this tool as much as I do.

Please feel free to leave a comment and/or corrections if you think I did something wrong :)

--

--