Mocha + RequireJS = AMD testing

Oskar Szura picture Oskar Szura · Dec 9, 2013 · Viewed 15.3k times · Source

I have a hard time connecting Mocha to RequireJS based application, may be You'll be able to come up with something :). After many hours when I've been trying to load AMD modules and simply console.log some 'fired' info that the module has been loaded... nothing happend had happened - the program just ended and printed out some mocha info.

var facade = requirejs(['../../public/js/scripts/widgets/widgets/article/main.js'],      
    function(mod) {
        console.log('fired')
});
// run with: $ mocha -u tdd test.js --reporter spec

and than I've come up with the idea to fire just this to test callbacks:

setTimeout((function() {
    console.log('fired');
}), 5000);
// run with: $ mocha -u tdd test.js --reporter spec

also didn't work. So finally I've run both with

$ node test.js 

and finally it worked. So question is than: How to run Mocha test with callbacks handling, as those are essential for AMD testing?

Answer

Louis picture Louis · Dec 9, 2013

The way you are doing it, mocha is not going to do anything with your file because it does not see a test suite in it. RequireJS is scheduled to call the callback but mocha exits before this has a chance to happen. Same with your timeout example.

The following gives you an example.

File test.js:

'use strict';
var requirejs = require("requirejs");
requirejs.config({
    baseUrl: '.',
    nodeRequire: require
});

suite('Something', function(){
    var foo;

    suiteSetup(function (done){
        // This saves the module foo for use in tests. You have to use
        // the done callback because this is asynchronous.
        requirejs(['foo'],
                  function(mod) {
            console.log("fired!");
            foo = mod;
            done();
        });
    });

  suite('blah', function(){
    test('blah', function(){
      if (foo.test !==  "test")
          throw new Error("failed!");
    });
  });
});

File foo.js:

define(function () {
   return {test: "test"};
});

When you run:

mocha -u tdd test.js

You'll see that the callback is fired and the test passes.

For the benefit of people reading this question and confused by the use of suite, suiteSetup, test... Mocha supports multiple interfaces. The code here is using the TDD interface (the OP invokes Mocha with -u tdd), which exports suite, suiteSetup, test, etc. In the default BDD interface, the equivalents are describe, before and it, respectively.