Creating Node Modules

Part 3 - Testing

Posted by Joel Lord on November 21th, 2015

Now that you've built your own module and that you've created and maintained a package.json file, you need to be sure that your module is actually tested.

What is unit testing

Unit testing makes sure that all of your methods in your module are returning the expected data. By enforcing unit testing, you add an extra safety net so that when you add new features to your module, you can see if you break anything which would make this backward incompatible.

Reorganize the folder structure

Before we get started, you will need to reorganize your folder structure a bit. If you start with the module you created in part 1, you will need to move the files in a src folder. This will let you create a test folder at the root of the module folder. The package.json file should stay at the root of the folder. The new file structure should look like this.

/test
/example
    index.js
/src
    randomNumber.js
package.json

You will notice that we moved the index.js in the example folder and that the only file in the src folder is the randomNumber.js file. We will now rename the randomNumber.js file to index.js as this is the main file for our module. Our final folder structure should look like.

/test
/example
    index.js
/src
    index.js
package.json

Because we moved the randomNumber.js file, we now have to manually update the package.json so that the "main" property is now "src/index.js" rather than "randomNumber.js".

Add the testing framework

Let's get ready to do some testing. In order to do so, we will need to add some packages to our project. Let's add Mocha as a testing framework and Chai for assertions.

npm install mocha --save-dev
npm install chai --save-dev

This should have added the node_modules folder to your project with the chai and mocha libraries in it. Because we added the --save-dev flag, it should have also update the package.json so that those libraries are now dependencies of this module.

Create a test file

Let's now add a test file for our project. We will ensure that our random number are valid by running the tests a few times. We will also make sure that setMin and setMax only accept numbers.

This is the test file that we are using

// test/index.js
var expect = require('chai').expect;
var randomNumber = require('../src/index');
describe('#randomNumber', function() {
    it('should be a number greater than 0 and smaller than 100', function() {
      for(var i = 0; i < 50; i++) {
          var result = randomNumber.generate();
          expect(result).to.be.above(0);
          expect(result).to.be.below(100);
      }
    });
    it("should always be greater than the minimum value and lower than the maximum value", function() {
      var min = 5;
      var max = 7;
      randomNumber.setMin(min);
      randomNumber.setMax(max);
      for (var i = 0; i < 50; i++) {
        var result = randomNumber.generate();
        expect(result).to.be.above(min);
        expect(result).to.be.below(max);
      }
    });
    it("should accept number for setMin", function() {
      var val = randomNumber.setMin("notANumber");
      expect(val).to.be.a("number");
    });
    it("should accept number for setMax", function() {
      var val = randomNumber.setMax("notANumber");
      expect(val).to.be.a("number");
    })
});

Run those tests

Let's now try to run those tests. In your command line, type the following

mocha test

This will run the index.js file found in the test folder. If you've followed me so far, your tests should be passed at 50%. The last 2 will fail as we have not built a testable code for those.

SYS0635:~ jlord$ mocha test


#randomNumber
✓ should be a number greater than 0 and smaller than 100
✓ should always be greater than the minimum value and lower than the maximum value
1) should accept number for setMin
2) should accept number for setMax


2 passing (17ms)
2 failing

1) #randomNumber should accept number for setMin:
 AssertionError: expected undefined to be a number
  at Context.<anonymous> (~/nodemodules/test/index.js:25:25)
....
2) #randomNumber should accept number for setMax:
AssertionError: expected undefined to be a number
at Context.<anonymous> (~/nodemodules/test/index.js:29:25)
....

Make all methods testable

Finally, we will make our setMin and setMax methods testable. In order to make so, we need to return a value. For those methods, we will return the value that is being set as a min/max. If the parameter is not a number, it should use default values. The new functions should look like this.

// src/index.js
....
//Expose a function to set the minimum random
//value
public.setMin = function(value) {
  if (isNaN(value)) value = 0;
  min = value;

  return value;
}

//Expose a function to set the maximum random
//value to be returned
public.setMax = function(value) {
  if (isNaN(value)) value = 100;
  max = value;

  return value;
}
....

We have now added a default value and a returned value. We can now run those tests again.

mocha test

And it should now be 4 passed out of 4.

Add to the package.json file

Let's keep our package.json file up to date. Now that we added a test framework, we should let npm run those tests for us.

Add the scripts property to the packages.json and enter the bash command to run the tests there.

//package.json
....
"scripts": {
  "test": "mocha test"
},
....

Test it with npm

Now that you've added the testing script to the package.json file, you should be able to run your tests using npm test.

SYS0635:~ jlord$ npm test

> random-number-gen@0.1.0 test /path/to/randomnumber
> mocha test

#randomNumber
✓ should be a number greater than 0 and smaller than 100
✓ should always be greater than the minimum value and lower than the maximum value
✓ should accept number for setMin
✓ should accept number for setMax


4 passing (13ms)

Summary

And that's it, you now have a node module with a testing framework. You are now very close to being able to publish. Stay tuned for our next blog post in this series !

<