How to Test Javascript code from 0 to Mocha
Tags: testing, javascript, codenewbie
Published: 2020-08-11 21:34:35

I’m trying to learn to test in javascript, today we have few ways to test our code write plain test code or using mocha, jest or cypress.

But what is a Test? the test is a piece of code that ensures our software works as we expect, it can be done without frameworks.

Feel free to read the code on [Github](https://github.com/danywalls/testing-js-with-mocka) or continue reading.

For this example, we will test a function for calculating IVA Tax of 21% from a single amount. the first step is to create a file iva.js and write the ivaCalculate function and export it.
```javascript
function ivaCalculate(amount, percentage) {
    return amount \* percentage / 100
}
module.exports = ivaCalculate
```
I will use nodemon package to run my js code quick and hot reload.

```bash
npm install -g nodemon
```
## The Test

Our second step is to create a spec file for our testing, the iva.spec.js file, import Iva.js using require and call the duction passing the parameters 1250 and 21, it will return the calculation from the function defined into the iva.js.

Validate the result === expect using a ternary and show a message is equal or not.
```javascript
const irpfCal = require('./iva');
const result = irpfCal(1250,21);
const expect  = 262.5;
result === expect ? console.log("ok") : console.log("fail")
```
From our terminal run to see the result of our “handy and dirty test”.
```bash
danys-imac:iva danyparedes$ nodemon iva.spec
[nodemon] 1.19.0
[nodemon] to restart at any time, enter \`rs\`
[nodemon] watching: \*.\*
[nodemon] starting \`node iva.spec.js\`
ok
[nodemon] clean exit - waiting for changes before restart
```
## Using the Assert Module

We are using a dump ternary function to validate our code, but nodejs bring with a module to handle these situations.

In our code, import assert module and it will provide a [list](https://www.w3schools.com/nodejs/ref_assert.asp) of assert methods, I use **equal**, it does the same behavior as our preview code.

The equal function evaluates if two values are not equal and if fails it throws an error and an optional message parameter for specifies the error.
```javascript
const assert = require('assert');
const irpfCal = require('./iva');
const result = irpfCal(1250,21)
const expect  = 262.5
assert.equal(result, expect, 'irpf calculation fails')
```
Our code will be reloaded by nodemon and it will not show any error but if we modify irpfCal function it will show irpf calculation fails.

## Move to Mocha

Our test works, but it is not easy to manage or provide an elegant way to see the results, for this case Mocha come to help us.

Mocha is a test runner, it will help to manage our test easier and it provides an elegant way to write, check and functions to evaluate our test.

First, install mocha test runner for our terminal in the same path.
```bash
npm install mocha --save-dev
```
When complete, edit the package.json and into the script area set tests to mocha.
```json
...
  "scripts": {
    "test": "mocha"
  }
 ..
```
By convention mocha search into test directory into our application, that means we need to create a test directory and move iva.spec.js file into it.

Mocha provides few global functions as **describe** it is used for the title of our group of tests, that means we can group few tests into a **describe** block and **it **for setting the title for a specific test.
```javascript
const assert = require('assert');
const irpfCal = require('../iva');
const actual = irpfCal(1250,21)
const expect  = 262.5describe('IVA tax calculation processs', () => {
    it('calculate 15% of 1250', () => {
        assert.equal(actual,expect)
    })
})
```
See the test results in the terminal running the command npm test
```bash
npm test
danys-imac:iva danyparedes$ npm test\> iva@1.0.0 test /Users/danyparedes/Desktop/testing/iva
> mocha
  IVA tax calculation processs
    ✓ calculate 15% of 1250
  1 passing (3ms)
```
## Extending the test

Create another function for the test, it will call **amountWithIVA,** add the function into iva.js and include it into the exports.
```javascript
function ivaCalculate(amount, percentage) {
    return amount \* percentage / 100
}function amountWithIVA(ivaAmount, amount) {
    return ivaAmount + amount;
}module.exports = { ivaCalculate, amountWithIVA }
```
I will group my set of test related to the iva into the describe **IVA tax calculation **and like the preview test it will call the function exposed by iva.js
```javascript
const assert = require('assert');
const {ivaCalculate, amountWithIVA} = require('../iva');describe('IVA tax calculation processs', () => {
    it('calculate 15% of 1250', () => {
        const actual = ivaCalculate(1250,21)
        const expect  = 262.5
        assert.equal(actual,expect)
    })
    it('calculate total amount of 1250,21 with 15% IVA', () => {
        const actual = amountWithIVA(1250,262.5)
        const expect  = 1512.50
        assert.equal(actual,expect)
    })
})
```
Run the test from the terminal with **npm test** and see the results.
```bash
danys-imac:iva danyparedes$ npm test
> iva@1.0.0 test /Users/danyparedes/Desktop/testing/iva
> mocha
  IVA tax calculation processs
    ✓ calculate 15% of 1250
    ✓ calculate total amount of 1250,21 with 15% IVA
  2 passing (5ms)
```
## Testing objects

My last example is a function to get a banner configuration for each IVA type, it returns an object with some settings, I will create a new file ads.js with the function getIVABanner it will return a json object.
```javascript
function getIVABanner(amount) {
    switch (amount) {
        case 15:
            return {
                img: '/bar.jpg',
                size: '15%',
                border: 3,
                color: 'green'
            }
            break;
        case 20:
                return {
                    img: '/bar.jpg',
                    size: '20%',
                    border: 5,
                    color: 'yellow'
                }
                break;
       case 30:
            return {
                img: '/bar.jpg',
                size: '20%',
                border: 5,
                color: 'red'
            }   
     default:
            break;
    }
}
module.exports  = { getIVABanner }
```

Next into the test directory create ads.spec.js , similar to iva.spec import assert from assert and gitIVABanner function from ads, using describe and to group all test related to ads for taxes.

Create the actual object calling getIVABanner function and pass 15 Tax type and define the expected object.

But in for the object, we will use assert.deepEqual to validate the actual match fully with the expected.
```javascript
const assert = require('assert');
const {getIVABanner} = require('../ads');describe('Ads for taxes', () => {
    it('Get green banner for 15% IVA', () => {
        const actual = getIVABanner(15);
        const expect =   {
            img: '/bar.jpg',
            size: '15%',
            border: 3,
            color: 'green'
        }
        assert.deepEqual(actual,expect)
    })
})
```
Run the npm test command to see the results.
```bash
danys-imac:iva danyparedes$ npm test
> iva@1.0.0 test /Users/danyparedes/Desktop/testing/iva
> mocha
  Ads for taxes
    ✓ Get green banner for 15% IVA
  IVA tax calculation processs
    ✓ calculate 15% of 1250
    ✓ calculate the total amount of 1250,21 with 15% IVA
  3 passing (7ms)
```
## That’s it!

Hopefully, that will give you a bit of a head-start on testing and Mocha, and help you avoid some of the more common mistakes, If you enjoyed this post, share it.

Thanks for reading!