Setup Mocha in watch mode for TDD in Node.js
Tags: codequality, tdd, mocha, typescript
Published: 2021-07-13 15:25:33

**Test-Driven Development** is a great development (not testing) methodology. It definitively helps you to produce :
* Minimal code to implement business needs
* Small functions 
* Code covered by tests, avoiding later regressions

We use it every day at [Promyze](https://promyze.com?utm_source=DevTo&utm_medium=referral) and we definitively saw the benefits of coding in this way. 


## Illustration 

Now, let's see how you can apply TDD with [Mocha](https://mochajs.org/) with **Typescript** on a **Node.js** project. 

All the code is available on this [Github project](https://github.com/promyze/node-tdd-watcher).

### Code Structure

In this example we have this simple structure :

```
.
├── domains
│   └── Bowling
│       ├── Game.spec.ts
│       └── Game.ts
├── LICENSE
├── package.json
├── package-lock.json
├── README.md
└── test
    └── mocha.spec.ts
```
*domains* contains our source code, and *test* contains my main test suite.

Let's have a look at the code now.

### package.json

The interesting part here is the **scripts** section. As you can see, we added the *--watch* option of Mocha in addition with the *--watch-files* option. Here, all the code in *domain* and *test* folders will be checked for modification, and tests will be automatically run again.

```json
{
    "name": "node-tu-wacher",
    "devDependencies": {
        "@types/chai": "^4.2.18",
        "@types/mocha": "^8.2.2",
        "@types/node": "^15.6.2",
        "chai": "^4.3.4",
        "mocha": "^8.4.0",
        "ts-node": "^10.0.0",
        "typescript": "^4.3.2"
    },
    "engines": {
        "node": ">=14.16.1"
    },
    "scripts": {
        "test": " mocha -r ts-node/register test/mocha.spec.ts",
        "test:watch": " mocha -r ts-node/register --watch --watch-files domains/**/*.ts,test/*.ts test/mocha.spec.ts"
    }
}
```

### test/mocha.spec.ts

This is the root test file that will import all my test suites :

```ts
import GameSpec from '../domains/Bowling/Game.spec';

import { Suite } from 'mocha';

describe('Server unit testing', function(this: Suite) {
        describe('Game', GameSpec);
    }
);
```

### domains/Bowling/Game.spec.ts

Here we assume that I've just started to code a Bowling app. I wrote my first test :

```ts
import { expect } from 'chai';
import Game from './Game';

export default function() {
    describe('Game testing', function() {
    
        it('should start a bowling game', async function() {
            const game = new Game();
            expect(game.currentScore()).to.eql(0);
        });

    });
}
```

### domains/Bowling/Game.ts

And here a basic implementation so that my first test can run :

```ts
export default class Game {

    private score: Number;
    
    constructor() {
        this.score = 0;
    }

    start(): void {
        this.score = 0;
    }

    currentScore(): Number {
        return this.score;
    }

}
```

## See it in action 

The command **npm run test:watch** will help me for my TDD session. Everytime a file is saved (CTRL+S with in your favorite IDE), tests would be run again.

```
cteyton@laptop:~/node-tu-watcher$ npm run test:watch

> node-tu-wacher@1.0.0 test:watch /home/cteyton/Work/Promyze/blog/node-tu-watcher
>  mocha -r ts-node/register --watch --watch-files domains/**/*.ts,test/*.ts test/mocha.spec.ts

  Server unit testing
    Game
      Game testing
        ✓ should start a bowling game


  1 passing (2ms)

ℹ [mocha] waiting for changes...
```

Get started now and have fun with TDD ;-)