2

I am developing a node module that uses jQuery's Deferreds and can't figure out the best way to test it.

The file src/MyModule.js looks like this:

var $ = require('jquery');

var MyModule = module.exports = function() {
    // constructor
};
// other module methods that use $.Deferred()

Example test code in test/MyModuleTest.js:

var test = require('tape');
var MyModule = require('../src/MyModule');

test('promise test', function(t) {
    t.plan(1);

    var module = new MyModule();
    var promise = module.promiseReturningMethod();
    promise.done(function() {
        t.ok(true);
    });
    module.resolveThePromise();
});

I would like to simply execute the tests like this: node test/MyModuleTest.js.

The code will eventually be passed through Browserify which will shim the require('jquery') so it uses the global jQuery object. My problem is how do I get the require('jquery') call from MyModule.js to work in the tests?

Running the test code currently gives the error:

TypeError: $.Deferred is not a function

This is because require('jquery') requires a window object to actually create the jQuery object. Otherwise, an empty object is returned.

I know I can use the following to make require('jquery') work in the test:

var myWindow = require('jsdom').jsdom().defaultView;
var $ = require('jquery')(myWindow);

This could be part of an answer but it's not the answer by itself! The code in MyModule.js should not have to hack around its require('jquery') call. The test code or infrastructure should somehow take care of this. But how?

Ragunath Jawahar
  • 19,513
  • 22
  • 110
  • 155
bernie
  • 9,820
  • 5
  • 62
  • 92

1 Answers1

2

You can intercept the require() call from your test file, using the mock-require package:

// test.js
var mock = require('mock-require');

var myWindow = require('jsdom').jsdom().defaultView;
var $ = require('jquery')(myWindow);

mock('jquery', $);
mock.reRequire('jquery'); // This will prevent require() calls to return the
                          // originally cached version of jQuery

// When MyModule will require("jquery"), it will get the one which uses jsdom's window
var MyModule = require("./MyModule.js");
Ragunath Jawahar
  • 19,513
  • 22
  • 110
  • 155
Nicolò
  • 1,795
  • 1
  • 16
  • 16