Monday, May 1, 2017

Testing an Express JS Application

We can use mocha, should, and supertest to test an express.js application. Mocha is used in creating test cases when unit testing, and executing them in a serial manner. Should is used to ensure that the response body is an Object, and have a property named _id. Supertest is used to test and ensure that the http calls are working properly.

As the first step in doing this, install mocha, should, and supertest by giving the commands:

    npm install mocha --save-dev
    npm install should --save-dev
    npm install supertest --save-dev

Then, make a new file with the name format <noun-name>.route.test.js. For example, it can be something like employee.route.test.js, and afterwards, go to the package.json file, and under "scripts", add:

   "test":"mocha \"./*.test.js\""

Then, import these three modules to the newly created file by using the require command.

Since we need the application for unit testing, we need to import that file as well. In order to do this, first go to the JavaScript file which has the application, and at the end of the file add the following line of code, so we could import the application later on, and use it.

   module.exports=app;

What we do here is, export the application made out of express, so that we could use it in unit testing. Note that app used in the above command should be the variable name given to the application made out of express using the command: const app=express();

After this step, import this file in the test file by giving the command(consider application file name to be server.js):  
   const app=require('./server');

Next step is to create the application using supertest by giving the command:
 const agent=request.agent(app);

Note that the name given in the place of the word request in the above command should be the variable name given when importing supertest using the line: const request=require('supertest');

What comes next is creating the basic structure for unit testing. The following command is given next in order to do that. Actually, what happens here is, a test suite is created. Ideally, a file should have only one test suite, but there can be cases where there is more than one test suite in a file.

  describe('Employee route test', ()=>{
    //place code here
});

Now we have to create a sample employee object to be used in testing the application. The following code will carry out that task, and it should be placed inside describe() where I have indicated by placing the comment: place code here.

 const employee={
   name:'Mary',
   email:'mary@gmail.com',
   tel:'1111111'
};

it() is used in creating test cases. Several test cases can be placed inside the test suite as we normally do. Now let's place our first test case inside the test suite. In this test case, we will be testing the POST rest method which we are using to insert an employee. The following test case code should appear below the above piece of code inside describe() in the file.

  it('should add new employee', (done)=>{
     agent.post('/employees')
         .send(employee) //parameters to be sent in the request body
        //which in this case is the sample employee object created           //above to test the inserting part of the application
         .expect(201)  //usual ok=>200 so if we have not added               //success response as 201, it is 200, depending on what you         //have used in the GET implementation in the application             //file.  
        //next comes the assertion part.
        .end(function(err, res){
           if(err){
               return done(err);
           }

           res.body.should.be.an.Object().and.have.property('_id');
           //this line expects and ensures that the body is an                  //Object and have a property named _id.

           done(); //used to signal mocha that the test case has                //been executed and that it can shift to the next test              //case in line to continue testing.
        });

      after(done=>{
           EmployeeModel.remove().then(()=>done()).catch(done);
      });
 })

The test case can now be tested to see whether it passes the test. In the same way, test cases to test other http methods can be written and tested in this test suite.


No comments:

Post a Comment