Category: mocha.js

Debugging Mocha tests in WebStorm

I’m a recent convert to the WebStorm IDE and for Node development especially, the debugger is a godsent. No longer do I need to add console.log statements to my code to figure out what’s going on, I can just set a breakpoint and go from there. Simply awesome! However, I wasn’t able to do this for Mocha test scripts. I tried these instructions that I found, but that didn’t work for me.

When I came across a post on Stack Overflow asking if Mocha could be used as a Node.JS module, I immediately figured out the solution. Create a Node.js script, include Mocha as a module and start the tests like that. Using the Mocha JS API, this was a simple task.

var Mocha = require('mocha'),
	path = require('path'),
	fs = require('fs');

var mocha = new Mocha({
	reporter: 'dot',
	ui: 'bdd',
	timeout: 999999
});

var testDir = './test/';

fs.readdir(testDir, function (err, files) {
	if (err) {
		console.log(err);
		return;
	}
	files.forEach(function (file) {
		if (path.extname(file) === '.js') {
			console.log('adding test file: %s', file);
			mocha.addFile(testDir + file);
		}
	});

	var runner = mocha.run(function () {
		console.log('finished');
	});

	runner.on('pass', function (test) {
		console.log('... %s passed', test.title);
	});

	runner.on('fail', function (test) {
		console.log('... %s failed', test.title);
	});
});

The only problem is the Mocha timeout setting. When you’re debugging, the timer will continue to run, so by the time you are done debugging, the timeout will have fired. Of course, this can be solved by setting the timeout value to a sufficiently high value for debugging. Running the tests can actually be done more easily by invoking mocha from the command line.

How to use Mocha.js to unit test YUI

We’ve recently started using YUI as the basis for a new version of our product. It’s a very solid library, which provides a lot of high quality code. And although YUI has a nice testing framework as well, we wanted to use Mocha.js, so we could run tests continuously. At first, it was unclear how to integrate YUI into Mocha tests, but in the end the solution was very simple:

var path = require("path"),
    YUI = require("yui3").YUI,
    chai = require("chai"),
    expect = chai.expect;

(function () {
    describe("MyModule", function () {
        var Y, myModule;

        before(function (done) {
            Y = YUI({
                modules: {
                    'mymodule': {
                        fullpath: path.join(__dirname, '../modules/mymodule.js')
                    }
                }
            }).use(['base','mymodule'], function () {
                done();
            });
        });

        beforeEach(function (done) {
            myModule = new Y.MyModule();
            done();
        });

        it('should instantiate the MyModule class', function (done) {
            expect(myModule).to.be.a('object');
            done();
        });

        it('should have a title', function (done) {
            myModule.set('title', 'test');
            expect(myModule.get('title')).to.be.equal('test');
            done();
        });

        it('should have a description', function (done) {
            myModule.set('description', 'test description');
            expect(myModule.get('description')).to.be.equal('test description');
            done();
        });
    });
})();

The trick is to use the ‘before’ method of Mocha.js to create a YUI sandbox and assign that to a variable that is in the larger scope, so it can be accessed in the other classes. To make sure everything has loaded, the ‘before’ method’s ‘done()’ call should be done inside the callback function of YUI’s use method.
And finally, the required YUI modules for custom modules aren’t loaded properly, unless they are mentioned in the use method’s first parameter.

Questions? Ping me on Twitter!