DEV Community

Cover image for Test-Driven Development with Nodejs, Express, Mongoose & Jest
Emmanuel Etukudo
Emmanuel Etukudo

Posted on • Updated on

Test-Driven Development with Nodejs, Express, Mongoose & Jest

Introduction

In this series, you will learn how to build and test a restful API with Nodejs, Express, and Mongoose using the TDD approach. You will also learn how to Architect your API-driven application from the ground up using the Layered-architecture approach. At the end of this series, you will be more confident writing code using the TDD approach.

Prerequisites:

To follow along in this tutorial you need to have basic knowledge of Javascript, Nodejs & Express as well as a good knowledge of how Restful API works.

Definition of terms

- Test-Driven Development (TDD)

Test-driven development (TDD) is a development technique where you must first write a test that fails before you write new functional code. TDD is being quickly adopted by agile software developers for the development of application source code and is even being adopted by Agile DBAs for database development.

- Jest

Jest is a JavaScript testing framework maintained by Facebook, Inc. designed and built by Christoph Nakazawa with a focus on simplicity and support for large web applications. It works out of the box with minimal configuration, although there are other testing frameworks, I find jest easy to follow along. you can dive deeper by reading through the official doc here

- Mongoose

Mongoose provides a straight-forward, schema-based solution to model your application data. It includes built-in type casting, validation, query building, business logic hooks, and more, out of the box all written to communicate with the MongoDB database. you can read about Mongoose here and MongoDB as well here.

Now that we are familiar with the technologies we will be working with while building our API, let's take look at our project overview.

  • Build a restful API
  • Testing the endpoints using Jest
  • Configure Jest to automatically run the test
  • Folder structure
  • MVC pattern (Model, View, Controller)
  • Layered-architecture

Next, let's proceed to set up our development environment. Copy-paste the code below in terminal for Mac users, and command prompt for Windows users, to set up a new project directory.

$ mkdir tdd-with-nodejs
$ cd tdd-with-nodejs
$ npm init -y
Enter fullscreen mode Exit fullscreen mode

If you got everything set up properly you should have the result below:

{
  "name": "tdd-with-nodejs",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC"
}
Enter fullscreen mode Exit fullscreen mode

Next, let's install the required dependencies for the development of our project. In your terminal cd into the root directory of your project, and copy-paste the code below:

$ npm i --save-dev express mongoose jest 
Enter fullscreen mode Exit fullscreen mode

Your package.json file should now look like the code below:

{
  "name": "tdd-with-nodejs",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "jest",
    "start": "nodemon index.js"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "express": "^4.17.1",
    "jest": "^26.6.3",
    "mongoose": "^5.11.9"
  },
  "dependencies": {
    "body-parser": "^1.19.0",
    "dotenv": "^8.2.0",
    "nodemon": "^2.0.6"
  }
}
Enter fullscreen mode Exit fullscreen mode

Now that we're all set, let's create a file named sum.js with a function named sum that sums up the value passed to its parameters (a,b), we will then proceed to create "sum.test.js**. to test the output of the function. These will help us to validate our Jest configuration.

Note: Jest behind the sense read test file in the test folder. so do well to put your **sum.test.js* file in the test folder.*

Creat a sum.js file within the root of your project directory and Copy-paste the code below into the file:

const sum = (a, b) =>{
    return a + b;
}

module.exports = sum;
Enter fullscreen mode Exit fullscreen mode

Create a new folder named test, navigate into the folder, create a file named sum.test.js, and Copy-paste the code below into the file to create your fest test:

const sum = require("../sum");

test('adds 2 + 2 to equal 4', () =>{
    expect(sum(2,2)).toBe(4);
});
Enter fullscreen mode Exit fullscreen mode

First test:

Open your terminal and cd into the root directory of your project, and copy-paste the code below to run your first test:

$ npm run test 
Enter fullscreen mode Exit fullscreen mode

if your got everything set up properly you should have a similar result to the screenshot below:

Screenshot 2021-01-03 at 14.00.15.png

Congratulations, you just successfully wrote your first test using Jest! That all for the [Part I] of this tutorial, see you in [Part II], where we will be building the API endpoints using the Layered-architecture approach.

Top comments (3)

Collapse
 
thxv3n0lvl profile image
thxv3n0lvl

Hey first of all thanks for the series and effort you put writing this out for us.

Noticed a couple things by just skimming and trying almost directly the code (not a good practice though) but hope this can be improved in this section of your articles.

1- It is mentioned that at some point jest configuration will be validated with the test itself.. I've noticed it's never configured... if someone is just copying/pasting (like me)... the sample wont work as the test script is not using Jest... npm's package.json by default states

 "scripts": {
      "test": "echo \"Error: no test specified\" && exit 1"
Enter fullscreen mode Exit fullscreen mode

I think as a minimum it should be edited to something like

"scripts": {
    "test": "jest"
Enter fullscreen mode Exit fullscreen mode

any other argument needed should be there.

2- I suggest to put commands like mkdir test && cd test and so on, as sometimes when this kind of details are just mixed with all the other text, it can be missed like I just did.
3- There are one or two typos, I recommend to check this out before posting the article to keep a higher quality.

Keep up the good work !

Collapse
 
eetukudo_ profile image
Emmanuel Etukudo

Thank you once again for your feedback, I forgot to update the package.json to;

{
  "name": "tdd-with-nodejs",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "jest",
    "start": "nodemon index.js"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "express": "^4.17.1",
    "jest": "^26.6.3",
    "mongoose": "^5.11.9"
  },
  "dependencies": {
    "body-parser": "^1.19.0",
    "dotenv": "^8.2.0",
    "nodemon": "^2.0.6"
  }
}
Enter fullscreen mode Exit fullscreen mode

The article has been updated accordingly.

Collapse
 
lcprog profile image
LC

I noticed that this works with a index.js with node, how different is this with the client react files?

thanks, great article