A crash course on testing with Node.js
Tags: programming, node, startup, javascript
Published: 2017-09-23 22:08:24

---
title: "A crash course on testing with Node.js"
published: true
tags: programming,nodejs,startup,javascript
canonical_url: https://hackernoon.com/a-crash-course-on-testing-with-node-js-6c7428d3da02
cover_image: https://cdn-images-1.medium.com/max/1024/1*xb953KRkHolnT1uPk6kM8Q.jpeg
---

JavaScript is a beautiful language. You must believe I’m crazy. Maybe you’re crazy for agreeing with me. But why would I say something like this? As a language, JavaScript gives you no support whatsoever. It bites your head off if you give it the slightest chance, and it has bizarre error messages if left unhandled. So you tell me, why is it beautiful?

Because it creates good, responsible, and intelligent developers. By worrying about getting your head ripped off by the smallest mistake, you adapt and overcome. The skill gained has less in common with programming and much more with a programmer’s state of mind. Because you are getting used to not having an invisible force guide you through the code. Instead, you rely on yourself, and your own skill. Hence, me stating something as crazy as I did&nbsp;above.

Why then, does this create good programmers? A good programmer is responsible, meticulous and reliable. Programmers like these make sure their code works. No matter which environment, or which machine. These masters of their craft, always cover code with tests, to ensure their work is valid. They have my utmost respect. I would like to believe they have your as&nbsp;well.

### Baby steps.

To lay the foundation of what a basic test case would look like let’s create a simple function.

```javascript
function addTwoNumbers(x, y) {
  return x + y;
}
console.log(addTwoNumbers(5, 1));
```

Calling this function we can see the result is 6. Because we know basic math, it makes perfect sense. But what if the function is really complex?

Let’s make sure to write a test case to ensure the function is valid no matter what.

```javascript
function addTwoNumbers(x, y) {
  return x + y;
}

function testAddTwoNumbers() {
  var x = 5;
  var y = 1;
  var sum1 = x + y;
  var sum2 = addTwoNumbers(x, y);

  console.log('addTwoNumbers() should return the sum of its two parameters.');
  console.log('Expect ' + sum1 + ' to equal ' + sum2 + '.');
  
  if ( sum1 === sum2 ) 
    return console.log('Passed.');
  
  console.log('Failed.');
}

testAddTwoNumbers();
```

See this? We’re defining the values to add, and creating their sum. Then we call `addTwoNumbers()` assigning it to another variable. Having done this, we’re ready to test the equality. What’re we expecting? Well, sum1 should be equal to sum2, if the function we created works as expected. Running this piece of code you should see the following get logged to the command&nbsp;line:

```bash
addTwoNumbers() should return the sum of its two parameters.
Expect 6 to equal 6.
Passed.
```

Congratulations, you’ve written your first unit test! The act of unit testing lies in writing tests for small units of code. Hence the name. Meaning you’ll write individual test cases for validating the behavior of functions, methods, and objects. Exactly like we did&nbsp;above.

What if we add a deliberate bug to our code? For the heck of checking if the unit test will fail gracefully. Change the `addTwoNumbers()` function&nbsp;to:

```javascript
function addTwoNumbers(x, y) {
  return x + x; // deliberate bug!
}
```

Run the unit test once again and you’ll see it fail like it&nbsp;should.

```bash
addTwoNumbers() should return the sum of its two parameters.
Expect 6 to equal 10.
Failed.
```

### A bit of&nbsp;theory.

A unit test consists of three&nbsp;parts.

1. Arrange
2. Act
3. Assert

From their names alone it is easy to comprehend what they stand for. Let’s break it down while looking at some&nbsp;code.

```javascript
function addTwoNumbers(x, y) {
  return x + y;
}

function testAddTwoNumbers() {

  // 1. ARRANGE
  var x = 5;
  var y = 1;
  var sum1 = x + y;

  // 2. ACT
  var sum2 = addTwoNumbers(x, y);

  console.log('addTwoNumbers() should return the sum of its two parameters.');
  console.log('Expect ' + sum1 + ' to equal ' + sum2 + '.');
  

  // 3. ASSERT
  if ( sum1 === sum2 ) 
    return console.log('Passed.');
  
  console.log('Failed.');
}

testAddTwoNumbers();
```

In the first part we **arrange** all necessary preconditions and inputs. You can see we defined the variables to add and the sum of these variables. The second step is to **act** on the function, object or method under test. Lastly, we **assert** that the expected results have occurred.

You may find the word assert a bit overwhelming. As a non-native English speaker, I sure did, when I first heard it. Not to worry, it only means _to claim._ You are asserting a truth, meaning you claim something is true. As simple as&nbsp;that.

> _Assertions_ are a tool to do basic sanity checking for programmer errors.
> — Marijn Haverbeke, [Eloquent JavaScript](http://eloquentjavascript.net/08_error.html#h_Sb9V3BEus1)

Want to write your own assertion? Sure you do. Check this&nbsp;out.

```javascript
var assert = {
  equal: function(firstValue, secondValue) {
    if (firstValue != secondValue) 
      throw new Error('Assert failed, ' + firstValue + ' is not equal to ' + secondValue + '.');
  }
};

function addTwoNumbers(x, y) {
  return x + y;
}

function testAddTwoNumbers() {

  // 1. ARRANGE
  var x = 5;
  var y = 1;
  var sum1 = x + y;

  // 2. ACT
  var sum2 = addTwoNumbers(x, y);

  console.log('addTwoNumbers() should return the sum of its two parameters.');
  console.log('Expect ' + sum1 + ' to equal ' + sum2 + '.');
  

  // 3. ASSERT
  try {
    
    assert.equal(sum1, sum2);
    
    console.log('Passed.');
  } catch (error) {
    console.log(error.message);
  }
  
}

testAddTwoNumbers();
```

On line 1 we instantiate a new object named assert, immediately adding a method called equal. If the two passed parameters are not equal, the function will throw an error. That’s it, that’s all the logic in the whole method. Now, on line 27 we’re wrapping the **assert** stage in a try catch block, and calling the assert.equal() method. Only if the values are not equal will an error be thrown and caught in the catch block. Otherwise, the thread of execution will continue and log 'Passed.' to the console. Go ahead and try it&nbsp;out!

### How about we get&nbsp;serious?

The examples above have shown the fundamentals of testing in general. Also pointing out the required mindset needed to succeed in the field of programming. It’s time to bring out the big guns. You’ll rarely ever use the code above in a production environment. Nevertheless, it’s crucial in the understanding of what is to&nbsp;come.

You can use many various tools to write tests for Node.js applications in production. An example is the built-in assertion library. Yes, Node does have assertions baked in. Only change line&nbsp;1.

```javascript
var assert = require('assert');

function addTwoNumbers(x, y) {
  return x + x;
}

function testAddTwoNumbers() {
  var x = 5;
  var y = 1;
  var sum1 = x + y;
  var sum2 = addTwoNumbers(x, y);

  console.log('addTwoNumbers() should return the sum of its two parameters.');
  console.log('Expect ' + sum1 + ' to equal ' + sum2 + '.');
  
  try {

    assert.equal(sum1, sum2);
    
    console.log('Passed.');
  } catch (error) {
    console.error('Failed.');
  }
}

testAddTwoNumbers();
```

By changing out our custom assert object for the built-in Node module our code works exactly the same. The default assertions in Node are extremely powerful, you can take a longer look at them&nbsp;[here](https://nodejs.org/api/assert.html).

However, tools like [Mocha](https://mochajs.org/) and [Chai](http://chaijs.com/) are the bread and butter of testing Node.js applications.

> **Mocha** is a feature-rich JavaScript test framework running on [Node.js](http://nodejs.org/) and in the browser, making asynchronous testing _simple_ and _fun_. Mocha tests run serially, allowing for flexible and accurate reporting, while mapping uncaught exceptions to the correct test — mochajs.org

> **Chai** is a BDD / TDD assertion library for [node](http://nodejs.org/) and the browser that can be delightfully paired with any javascript testing framework.  — chaijs.com

Let’s check this out. First of all, you’ll need to `init` a new Node project by hooking it up to&nbsp;npm.

Open up a terminal window in your directory of choice, and&nbsp;run:

```bash
npm init
```

Please feel free to enter through all of the prompts. When you’ve done that, you’ll need to install the required&nbsp;modules.

```bash
npm install --save-dev mocha chai
```

Now you can open up your code editor of choice and start by adding files like&nbsp;so:

```bash
> test
  - test.js
- addTwoNumbers.js
```

One _test_ directory with a _test.js_ file, and another file named _addTwoNumbers.js_ in the root of the directory. Go ahead and paste the addTwoNumbers function into the _addTwoNumbers.js_ file like&nbsp;so:

```javascript
function addTwoNumbers(x, y) {
  return x + y;
}
module.exports = addTwoNumbers;
```

Don’t forget to export it to be able to require it later on. Now we can start with the fun part. Open up _test.js_ and start by laying the foundation for our&nbsp;tests.

```javascript
var expect = require('chai').expect;
var addTwoNumbers = require('../addTwoNumbers');

describe('addTwoNumbers()', function () {
  it('should add two numbers', function () {
    
    // 1. ARRANGE
    var x = 5;
    var y = 1;
    var sum1 = x + y;

    // 2. ACT
    var sum2 = addTwoNumbers(x, y);

    // 3. ASSERT
    expect(sum2).to.be.equal(sum1);

  });
});
```

At the beginning of the file we need to require both _Chai_ and _addTwoNumbers_. Look at the way we required _Chai_, only grabbing **expect**. _Chai_ comes with three types of interfaces for creating assertions. They are all valid. Which one you choose is only preference. I feel like expect suits me just fine. Don’t get mindblown by the test syntax. It’s created to simulate natural human speech patterns. The describe block creates a test environment. The it blocks defines test cases which need to pass. Reading it out loud sounds rather fine. Describe addTwoNumbers(), it should add two numbers. Makes perfect sense! Can you now see why testing is important apart from making sure the code works? A test is in itself documentation. Writing a test will explain what the code does. Every other developer working on the code base will have no issue understanding it in no&nbsp;time.

All that’s left is to run the tests. Add "test": "mocha" in the scripts section of your _package.json_ and you’ll be ready to&nbsp;go!

> **Hint** , your **package.json** should look like&nbsp;this:
```javascript
{
  "name": "testing",
  "version": "1.0.0",
  "description": "",
  "main": "test.js",
  "directories": {
    "test": "test"
  },
  "scripts": {
    "test": "mocha"
  },
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "chai": "^4.1.1",
    "mocha": "^3.5.0"
  }
}
```

Jump back to your terminal window and run npm test. You’ll see an awesome interface with some green text saying there is 1 passing&nbsp;test!

![](https://cdn-images-1.medium.com/max/1024/1*K4ELiBlIVfiFYMMMKE1b2w.png)

### Taking it all&nbsp;in.

You’ve now experienced the natural process of covering code with tests. All the examples have been showing unit tests, which is more than enough to begin with. When you get comfortable with these concepts, understanding integration and end-to-end testing will be like a walk in the park. But that’s a topic for another&nbsp;article.

I urge you to continue playing with these testing tools. Try to include them into your existing development process. You will see an overall improvement in code quality and mental health. Trust me, having peace of mind with a completely green test suite does wonders for the&nbsp;nerves.

If you want to take a look at all the code we wrote above, [here’s the repository](https://github.com/adnanrahic/a-crash-course-on-testing-with-nodejs). Or if you want to read my latest articles, head over&nbsp;here.

[Latest stories written by Adnan Rahić - Dev.to()](https://dev.to/adnanrahic)

_Hope you guys and girls enjoyed reading this as much as I enjoyed writing it. Do you think this tutorial will be of help to someone? Do not hesitate to share. If you liked it, click the_ **cute unicorn** _below._

* * *

<a href="https://www.buymeacoffee.com/adnanrahic" target="_blank"><img src="https://bmc-cdn.nyc3.digitaloceanspaces.com/BMC-button-images/custom_images/white_img.png" alt="Buy Me A Coffee" style="height: auto !important;width: auto !important;" ></a>