Project Best Practices: Adding Integration Tests

In this tutorial, we will get you set up running integration tests with ExpressJS. While I will be using a specific library, you can generalize these methods to meet the app you are using.

Integration tests will differ from Unit tests in the sense that they treat the app as a block box. For us, we will be testing our API which means sending API calls and checking the returns.

Set Up

Run the following commands to get a clean project

mkdir test-integrations
cd test-integrations
npm init -y
touch index.js
mkdir test

Initial Api

Now, create our basic API with one route

npm install express --save

Then in the index.js file

const express = require('express')
const app = express()

app.get('/hello-world', (req, res) => {
  return res.status(200).send({msg: 'Hello World!'})
})

app.listen(3000, () => console.log('Example app listening on port 3000!'))

module.exports = app;

This is basically the hello world example form ExpressJS’s site, but I’ve change the return value to JSON so we can test it as if we were working on a real world API.

Creating our test

Let’s start by installing our test libraries.

npm install mocha chai chai-http --save
  • We will be using chai to do assertions. For example. expect(1 === 1).to.eql(true)
  • We will use chai-http to make requests to our API
  • And finally, we will use mocha to run our test and organize them

All of this will make more sense with an example 🙂

Let’s create a file in our test directory. You can name your file how you’d like, but this is my preferred format.

touch test/GET-hello-world.test.js

In the above file, let’s add the following to the top of the file

// Testing Libraries
const chai = require('chai');
const chaiHttp = require('chai-http');

// Api
const server = require('../index');

// Global to help with code style
const expect = chai.expect
chai.use(chaiHttp);

This will import our testing libraries and our api. We also tell chai to use the http module and create a global expect variable to keep our tests concise.

Now, add the first test

describe('/GET Triggers', () => {
  it('returns hello world', async () => {
    const response = await chai.request(server).get('/hello-world');

    expect(response.status).to.eql(200);
    expect(response.body.msg).to.eql('Hello World!');
  });
});

Here we use a function called describe which simply organizes our tests into a group. You will see this in the output after we run the test. You can also declare describe sections inside other describes.

The second function is the it function which defines a specific test. You can see here that we use chai to call a request to our server. Afterword we use the expect global variable to assert our status and body on the response.

Create an error test

Let’s also create an error test so you can see how that work. We will call an api route that does not exists and check that express returns a 404.

Inside of the describe function add the following

it('errors route is not found', async () => {
  try {
    await chai.request(server).get('/fake-url');
  } catch (e) {
    expect(e.response.status).to.eql(404);
  }
});

Conclusion

Here is the final result of our code

// Testing Libraries
const chai = require('chai');
const chaiHttp = require('chai-http');

// Api
const server = require('../index');

// Global to help with code style
const expect = chai.expect
chai.use(chaiHttp);

describe('/GET Triggers', () => {
  it('returns hello world', async () => {
    const response = await chai.request(server).get('/hello-world');

    expect(response.status).to.eql(200);
    expect(response.body.msg).to.eql('Hello World!');
  });

  it('errors route is not found', async () => {
    try {
      await chai.request(server).get('/fake-url');
    } catch (e) {
      expect(e.response.status).to.eql(404);
    }
  });
});

As you can see, it is easy to get started! Basically you call a request to your api routes, then check the output. There is much more detail we can get into, but we shall cover that in later lessons.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s