How to Write Unit Tests for Your REST API

Testing our models and UI isn’t enough — we need to test our APIs too

Oyetoke Tobi Emmanuel
May 7 · 9 min read
Photo by Ferenc Almasi on Unsplash

When building software, we often forget the importance of testing. Testing not only ensures your application or system is working as expected, but it also helps manage new changes in specification or implementation.

We can’t know whether the system is working as it should be unless there’s a mechanism in place to check if the system works well after new changes.

There are different types of testing for different test approaches. However, the most popular and important is unit testing. Unit testing is basically testing if a unit or component of the system is working as expected. You either just call the component, if no input is required, or give it an input and determine the output.

In the context of REST API, a unit is a single endpoint request, and writing a unit test for this particular API depends on what you want to test in its response base on the request sent.

In a single API endpoint request, you can test its response for the combination of:

  • Response body
  • Response header (authorization)
  • Response status code

With this, you’re able to assert the expected response body, header, and status code. This process requires an HTTP request client library, an assertion library, a testing framework and a bit of coding to get the optimal output.

There are also ways to test your API without writing a single line of code, like Loadmill, which we’ll look at later in this article.

First, let’s look at how to write a unit test for REST APIs with Node.


Setting Up a REST API

To get started, we need to have a REST API up and running. We’ll be writing unit tests for each of the API endpoints. For this article, I’ve set up a basic express rest API that we’ll be using. You can either set it up manually, by cloning the codebase here, or use the hosted version here.

Note: You can skip this step if you don’t want to set up the REST API locally.

To set it up locally:

$ git clone git@github.com:CITGuru/store-ordering-api.git
$ cd store-ordering-api
$ npm install

Note: Ensure you have MongoDB set up locally.

Once you have everything set up, you can run the REST API:

npm start

To test it, open http://localhost:3200.

I’ve made a simple doc on how it works — check it out on/docs.

That’s it! Our Rest API is up, we can now set up our testing environment.


Setting Up a Testing Environment on Node

To get started, we need to create a new npm project and install the required dependencies to get things working.

mkdir rest-api-testing && cd rest-api-testing
npm init -y
npm install chai chai-http mocha

In this tutorial, we’ll be using Chai for the assert library, Chai-Http for HTTP request client library, and Mocha for our test framework.

Next, we need to write a simple unit test to test our set up.

Create a new file, first_test.js:

To run the above test:

mocha first_test.js --timeout 100000

If all goes well, you should see something like this:

That’s it — our first test passed! With this, we can be assured that our test environment works fine.


Writing Unit Tests For Our API Endpoints

Now, let’s look at writing a unit test for each of the API endpoints. If you’ve had the chance to check the API doc I mentioned earlier, you would see that we have seven endpoints and we’ll be writing a unit test case for each.

Here are the endpoints:

  • Request for a token (POST): /request-token
  • Create a new order (POST): /new_order
  • Get an order (GET): /orders/:id
  • Get all orders (GET): /orders
  • Update an order (PUT): /orders/:id
  • Delete an order (DELETE): /orders/:id
  • Filter orders (GET): /orders/:id

Now let’s create a boilerplate for all our test unit cases. Create a file order_test.js:

Let’s take each of the units and write a test to verify it works as expected.

Request for a token

In order to access the other six endpoints, you need a token that you send along with the request headers, enabling you to create, retrieve, and access other endpoints. To get a token, send a POST request to /request-token:

In the above test case, we:

  • Sent a post request to the request-token endpoint.
  • Check if the response status code is 201.
  • Check if the response body has the token property that holds the token for authentication.
  • Then assign the token for subsequent tests that will need the token for authentication.

We run the test case the same way as earlier:

mocha order_test.js --timeout 100000

We should get this:

Create a new order (POST)

This endpoint basically creates a new order. We need to send the data of the order we want to create as well as pass along the token in the request headers.

Here’s an example of the order data:

{
"name":"Sandine (Milo)",
"customer_email":"oyetoketoby80@gmail.com",
"customer_name":"Oyetoke Toby",
"quantity":5,
"customer_address": "Aboru, Lagos"
}

For authentication, you need to send this:

Authorization: Basic <token>

This is the typical response you get:

With all these we can write our test as below:

https://gist.github.com/BetterProgramming/5c08fd11ad93d5bf90ad790645c2c7de.js

Now we have added orderId, we’ll use it in subsequent test cases — to get an order, update order, and so on.

Running this should output the following:

Get an order (GET)

This endpoint accepts an order ID and returns its data. We’ll use the orderId from the previous test case and try to get the same data as before. The endpoint will be in this format:

/orders/<orderId>

Here’s a typical response if you try to get an order:

We can write the test as below:

The output of the test result should be:

Get all orders (GET)

This basically returns all the orders. In this case, we’ll be testing if the previously created order is in the list of returned orders:

In this case we:

  • Check whether the response body is an array
  • Loop through the list of orders and see if can find any orders with the same ID as the orderId we have.

If all these passed, you should see this result:

Update an order (PUT)

This endpoint accepts an order id and updates the status, quantity and address properties of the order.

The endpoint format is the same as the one we used in getting an order test case. In this test case, we’ll update either of the property of the order and assert if it’s updated. We’ll be sending a PUT request, along with the data we want to update.

Here’s a typical response when updating an order:

Our test is as shown:

The output should be as below:

Delete an order (DELETE)

This is the same step as updating an order. In this case, we’ll delete an order using its order ID, then try to get it back and see if we get a 404 message.

Here’s a typical response when deleting an order and trying to get the same order back:

Here’s our test:

Our test should output this:

Filter orders (GET)

As the name implies, this endpoint filters orders base on matching URL queries. Let’s say you want to get all cancelled or completed orders, you just send a request to /orders/filter?status=completed and this would return all orders with completed status.

In this test case, you need to grab a token or use 0f8ae605–24b5–4ecf-b260–777a9ba490f5 and declare it manually in your code. Then create multiple orders using the /new_order endpoint, so you have enough data to test with.

Once you’re done, we can write our test:

In this case, we looped through the returned orders and ensured that all the orders returned have completed status.

That’s it! All our tests have passed. We’ve seen how to write a simple unit test for each of our API endpoints.


Test Your Rest API Without a Single Code

No-code is a concept I’m sure you’re aware of and can’t wait to test out. Basically, it means you don’t have to go through all the steps of setting up a test environment in order to test your Rest API as Loadmill does a lot of the work for you.

To start using Loadmill, head over to their website and create a new account. Once you have successfully created an account and logged in, click on API Tests located on the navbar. Then click on New Test Suite.

You should see something like this:

There are various things you can do here, but our aim is to test our Rest API.

The above image is where most of the work is done. You can give your test a name. If you’re sending a request, select the request method the API endpoint accepts from the method selection box. Then provide the URL you’re sending the request to. If you’re sending a POST request, you can provide the data of the post request in the “Body” section.

Basically, you have the same capabilities as writing code but it’s easier.

Request a token

Let's grab the first endpoint we’ll be testing, the request token:

The next things we need to do:

  • Test whether we get a success response code.
  • Test whether the token path is returned and extract the token for later use.

To run our test, click the play button:

You should see the results of the test, as below:

Create a new order

Next, grab the token from the previous test result, then click Add Request to create a new request.

Running the tests display:

That’s it! There’s more you can achieve just using the test tool, without writing a single line of code.


Conclusion

Now that we have a better understanding of what unit testing is and how to write one for our REST API, we can see it has a lot of benefits.

They are simple test cases that cover a narrow block of logic. They can serve as a building block for ensuring changes to your API have not broken fundamental logic elsewhere. With the example we have explored, we can say unit tests are quick to write since they are usually very narrowly-scoped code or no code.

Unit tests are just one of many software testing methods for testing your REST APIs. They should be used wherever it is appropriate.

In this article, we’ve been able to cover the basics of writing a unit test for our REST API. In the next article, we’ll explore how to write more comprehensive unit testing.

Better Programming

Advice for programmers.

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade

Get the Medium app