DEV Community

loading...
Promyze

Setup Mocha in watch mode for TDD in Node.js

Cédric Teyton
・2 min read

Test-Driven Development is a great developement (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 everyday at Promyze and we definitively saw the benefits of coding in this way.

Illustration

Now, let's see how you can apply TDD with Mocha with Typescript on a Node.js project.

All the code is available on this Github project.

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
Enter fullscreen mode Exit fullscreen mode

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.

{
    "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"
    }
}
Enter fullscreen mode Exit fullscreen mode

test/mocha.spec.ts

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

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

import { Suite } from 'mocha';

describe('Server unit testing', function(this: Suite) {
        describe('Game', GameSpec);
    }
);
Enter fullscreen mode Exit fullscreen mode

domains/Bowling/Game.spec.ts

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

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);
        });

    });
}
Enter fullscreen mode Exit fullscreen mode

domains/Bowling/Game.ts

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

export default class Game {

    private score: Number;

    constructor() {
        this.score = 0;
    }

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

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

}
Enter fullscreen mode Exit fullscreen mode

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...
Enter fullscreen mode Exit fullscreen mode

Get started now and have fun with TDD ;-)

Discussion (0)