Testing NodeJS API with Mocha and Chai

  • January 03, 2020
  • Suraj Roy

While working on a big project, It's also very necessary to check the written API should work well while making the app or while making some changes later on. Writing test cases allow us easily track if any error occurs in any instance.

 

In this tutorial, We will learn to write test cases for Node.js Restful API using Mocha and Chai. We will mainly test a Get API and a POST API to have a basic understanding of how to start writing test cases. If you want to know about the very basics of testing in Nodejs and about the Mocha and Chai, then you can read my recently posted article about the Basics about Writing Tests in Nodejs API Application

 

Let's Get Started

Create Node.js App

Create a project folder and move to it.

mkdir test-with-mocha && cd test-with-mocha/

 

Create package.json file with NPM command

npm init --yes

 

Above command will create package.json file with default values

Install needed NPM package

npm install express

 

Now install dev dependencies

npm install mocha chai chai-http faker --save-dev

Mocha: Mocha is a javascript framework for Node.js which allows Asynchronous testing.

Chai: Chai is a BDD / TDD assertion library for node and the browser that can be delightfully paired with any javascript testing framework.

chai-http: Chai HTTP provides an interface for live integration testing via superagent.

faker: It is useful for creating dummy data while making HTTP requests.

 

Server File(app.js)

 

 
//Load express module
const express = require('express'),
app = express(),
bodyParser = require("body-parser"),
faker = require('faker');
 
 
app.use(bodyParser.json());
 
//Define request response in root URL (/)
app.get('/', (req, res)=> {
  res.send('App running successfully!');
})
 
// Create a basic get API with some response...
app.get('/post-list', (req,res)=>{
  if(!req.query.user_id || req.query.user_id==""){
    res.status(401).send({"message":"User Id parameter is missing"})
  }
  else{
    res.json({
      "userId": 1,
      "id": 1,
      "title": "sunt aut facere repellat provident occaecati excepturi optio reprehenderit",
      "body": "quia et suscipit\nsuscipit recusandae consequuntur expedita et cum\nreprehenderit molestiae ut ut quas totam\nnostrum rerum est autem sunt rem eveniet architecto"
    })
  }
 
})
 
// Dummy post API with some input params and response.
app.post('/submit-data', (req,res)=>{
  if(!req.body.name || !req.body.email){
    res.status(401).json({
      message : "Mandatory params are missing!"
    })
  }
  else{
    res.status(200).json({
      message : "data saved successfully"
    })
  }
})
 
//Launch listening server on port 8080
app.listen(4000, ()=> {
  console.log('App listening on port 4000!')
})
 
module.exports = app;
 

 

Start writing Tests with Mocha and Chai

 

At first add below line in package.json file for testing purpose.

"test": "./node_modules/.bin/mocha test --timeout 0 --exit"

 

Create a test file named index.js inside newly created folder named test.

 

Write a simple test case to check if the server is running properly. 

 

 
const chai = require('chai'),
chaiHttp = require('chai-http'),
server = require('../app'),
faker = require('faker'),
should = chai.should();
 
chai.use(chaiHttp);
 
describe('Init', function () {
 
it('check app status', function (done) {
  chai.request(server).get('/').end((err, res) => {
    should.not.exist(err);
    res.should.have.status(200);
    done();
  })
});
 
});
 

 

Now run the test with command npm test.

success

 

Test Cases for get API

 

Now let's move to test get API with its different cases.

 
describe('/Get API test', function () {
 
  it('Check the api without user id parameter', function (done) {
    chai.request(server).get('/post-list').end((err, res) => {
      should.not.exist(err);
      res.should.have.status(401);
      res.body.should.be.a('object');
      res.body.should.have.property('message');
      res.body.should.have.property('message').eql('User Id parameter is missing');
      done();
    })
  });
 
  it('Check the api with user id. Success', function (done) {
    chai.request(server).get('/post-list?user_id=1').end((err, res) => {
      should.not.exist(err);
      res.should.have.status(200);
      res.body.should.be.a('object');
      res.body.should.have.property('userId');
      res.body.should.have.property('title');
      res.body.should.have.property('body');
      done();
    })
  });
 
});
 

 

In the above code, we have tested two cases, the first case is to test on hitting API without parameter and the second is with valid parameter to get success response. There may other cases but for simplicity, I have written only two cases now.

after running npm test below outcome will be there on the terminal

test get api

Now since we have total of 3 test cases, So it's showing 3 passing and also we can see the name of cases passed.

 

Test Case for Post API

 

 
describe('/POST API test', function () {
 
  it('Check the api without parameters . failure case', function (done) {
    chai.request(server).post('/submit-data').send({}).end((err, res) => {
      should.not.exist(err);
      res.should.have.status(401);
      res.body.should.be.a('object');
      res.body.should.have.property('message');
      res.body.should.have.property('message').eql('Mandatory params are missing!');
      done();
    })
  });
 
  it('Check the API with valid parameters. Success', function (done) { 
    chai.request(server).post('/submit-data').send({name:faker.name.firstName(),email:faker.internet.email()}).end((err, res) =>
      should.not.exist(err);
      res.should.have.status(200);
      res.body.should.be.a('object');
      res.body.should.have.property('message');
      res.body.should.have.property('message').eql('data saved successfully');
      done();
    })
  });
 
});
 

 

Here we have tested two cases of post API, which can be many more. One if failure case and other is success case, I have used here faker for creating dummy data while making the HTTP request. 

After running npm test command on terminal we will get like below:

 

Great, our tests are all positive and we have now good understanding to start writing test cases for live application.

 

Complete test file(test/index.js)

 

 
const chai = require('chai'),
chaiHttp = require('chai-http'),
server = require('../app'),
faker = require('faker'),
should = chai.should();
 
chai.use(chaiHttp);
 
describe('Init', function () {
 
  it('check app status', function (done) {
    chai.request(server).get('/').end((err, res) => {
      should.not.exist(err);
      res.should.have.status(200);
      done();
    })
  });
 
});
 
// Test a get route...
 
describe('/Get API test', function () {
 
  it('Check the api without user id parameter', function (done) {
    chai.request(server).get('/post-list').end((err, res) => {
      should.not.exist(err);
      res.should.have.status(401);
      res.body.should.be.a('object');
      res.body.should.have.property('message');
      res.body.should.have.property('message').eql('User Id parameter is missing');
      done();
    })
  });
 
  it('Check the api with user id. Success', function (done) {
    chai.request(server).get('/post-list?user_id=1').end((err, res) => {
      should.not.exist(err);
      res.should.have.status(200);
      res.body.should.be.a('object');
      res.body.should.have.property('userId');
      res.body.should.have.property('title');
      res.body.should.have.property('body');
      done();
    })
  });
 
});
 
describe('/POST API test', function () {
 
  it('Check the api without parameters . failure case', function (done) {
    chai.request(server).post('/submit-data').send({}).end((err, res) => {
      should.not.exist(err);
      res.should.have.status(401);
      res.body.should.be.a('object');
      res.body.should.have.property('message');
      res.body.should.have.property('message').eql('Mandatory params are missing!');
      done();
    })
  });
 
  it('Check the API with valid parameters. Success', function (done) {
    chai.request(server).post('/submit-data').send({ 
      name: faker.name.firstName(),
      email: faker.internet.email()
    }).end((err, res) => {
      should.not.exist(err);
      res.should.have.status(200);
      res.body.should.be.a('object');
      res.body.should.have.property('message');
      res.body.should.have.property('message').eql('data saved successfully');
      done();
    })
  });
 
});
 

 

Conclusion

In this article, we learned about how to start writing test cases for Node.js Restful API. So writing test cases for Nodejs Restful API is not very difficult.

If you are new to Node.js then find Nodejs Sample Application to start the app for enterprise-level application.

Let me know your thoughts over email demo.jsonworld@gmail.com. I would love to hear them and If you like this article, share with your friends.

 

Thank You!

 

You can download complete code from here. Download Code


Find other similar demo here: