Integration Testing for Express-Mongoose App
In my previous blog, I talked about unit testing. With unit testing, you can check if the various units of your code are functioning properly. But that is not enough. In the end, the units should work properly after integration not just individually. Let's see how we can make sure of that.
I am taking an example of a node app which uses express for routing and mongoose for interaction with MongoDB. We will write integration tests for this node app. But first, let us see what is integration testing.
Integration testing is the phase in software testing in which individual software modules are combined and tested as a group. Integration testing is conducted to evaluate the compliance of a system or component with specified functional requirements.
In this project, we have two routes.
- /save POST method: This is used to get some data about students and save it in the database(Create operation).
- /:id GET method: This route queries the data of student with the specified id from the database(Read operation) and sends it in response.
Code for PUT route used for update operation and DELETE route used for delete operation is in this GitHub repo.
Use the following command in terminal to install the required dependencies.
npm install express mongoose body-parser --save
This will be the folder structure of our project:-
Code for app.js:-
Code for student.js which specifies the schema for the studentlist collection. It is placed in the models folder:-
Code for dbConnect.js which establishes the connection to MongoDB database. It is placed in the helpers folder:-
Now let’s start the testing part. Use the following command to install the development dependencies:-
npm install mocha chai supertest --save-dev
Add the following scripts to you package.json
"start": "node app.js",
"test": "mocha --recursive --exit --timeout 10000"
Now we will create the basicSetup.js file. It creates hooks which would be used by the test scripts. Hooks are configured to run before or after tests. Mocha has four hooks for the BDD interface:-
- before( ): Runs before the first test case of the describe block it is placed in
- beforeEach( ): Runs before each test case of the describe block it is placed
- after( ): Runs after the last test case of the describe block it is placed in
- afterEach( ): Runs after each test case of the describe block it is placed in
For testing asynchronous code using mocha we can use the done( ) callback. After the asynchronous task is completed we need to call it.
- CASE1: We call done( ) without passing any value when everything works fine. Example:-
// async code
- CASE1: We call done( ) and pass some value to it if some error occurs. Example:-
done('when some error occurs');
Here is documentation from mocha for more details about testing asynchronous code.
Code for basicSetup.js
While writing the test cases we should ensure that we cover all possible conditions that may occur when the application goes into production.
Now let’s write the test cases for the /save route which is responsible for inserting data sent to it into the database. Create insertData.test.js inside test folder and write the following code.
Now let’s write the test cases for the /:id route which requests the data of student with the specified id. We query the database for a student with the given id and send the data as a response. Create readData.test.js inside test folder and write the following code.
Finally, it’s time to run the tests. Use the following command for that:-
npm run test
Here is the sample output for all the four routes( see GitHub repo for the code of other two routes).
I hope this blog will help you write tests from next time for your serverside code. Feel free to write a comment and give some claps if you find this blog helpful.