Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to mock global variables (define, module, window) in mocha tests?

In the pursuit of 100% code coverage, I am attempting to use mocha to test that my javascript module is loading correctly under AMD, CommonJS/Node, and browser conditions. The pattern I'm using is below:

my-module.js

(function(global){

  function MyClass(){}

  // AMD
  if(typeof define === 'function' && define.amd){
    define(function(){
      return MyClass;
    });

  // CommonJS/Node
  } else if (typeof module !== 'undefined' && module.exports){
    module.exports = MyClass;

  // Browser
  } else {
    global.MyClass = MyClass;
  }

})(this);

Since I am running my tests with node, define is never defined, and module is always defined; so the "CommonJS/Node" condition is the only one that ever gets tested.

What I have tried so far is something like this:

my-module.test.js

var MyClass = require('./my-module');

describe('MyClass', function(){
  // suite of tests for the class itself
  // uses 'var instance = new MyClass();' in each test
  // all of these tests pass
});

describe('Exports', function(){
  // suite of tests for the export portion
  beforeEach(function(){
    MyClass = null; // will reload module for each test
    define = null; // set 'define' to null
    module = null; // set 'module' to null
  });

  // tests for AMD
  describe('AMD', function(){
    it('should have loaded as AMD module', function(){
      var define = function(){};
      define.amd = true;

      MyClass = require('./my-module'); // might be cached?
      // hoping this reloads with 'define' in its parent scope
      // but it does not. AMD condition is never reached.

      expect(spy).to.have.been.called(); // chai spy, code omitted
    });
  });
});

I'm using spies to check if define has been called, but the module doesn't show any signs of ever being reloaded with define available to it. How can I achieve that?

And is there a safe way of nullifying module so that I can test the browser condition as well?

like image 860
SteamDev Avatar asked Feb 05 '15 01:02

SteamDev


1 Answers

You might want to check out the rewire module. I'm not 100% sure, but I think it'll let you do what you need.

https://github.com/jhnns/rewire

like image 106
Kevin Ennis Avatar answered Sep 28 '22 11:09

Kevin Ennis