title: How to mock global variables (define, module, window) in mocha tests?
body: <p>In the pursuit of 100% code coverage, I am attempting to use mocha to test that my javascript module is loading correctly under <strong><code>AMD</code></strong>, <strong><code>CommonJS/Node</code></strong>, and <strong><code>browser</code></strong> conditions. The pattern I'm using is below:</p>
  
  <p><strong>my-module.js</strong></p>
  
  <pre><code>(function(global){
  
    function MyClass(){}
  
    // AMD
    if(typeof define === 'function' &amp;&amp; define.amd){
      define(function(){
        return MyClass;
      });
  
    // CommonJS/Node
    } else if (typeof module !== 'undefined' &amp;&amp; module.exports){
      module.exports = MyClass;
  
    // Browser
    } else {
      global.MyClass = MyClass;
    }
  
  })(this);
  </code></pre>
  
  <p>Since I am running my tests with node, <code>define</code> is never defined, and <code>module</code> is always defined; so the "CommonJS/Node" condition is the only one that ever gets tested.</p>
  
  <p>What I have tried so far is something like this:</p>
  
  <p><strong>my-module.test.js</strong></p>
  
  <pre><code>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
      });
    });
  });
  </code></pre>
  
  <p>I'm using spies to check if <code>define</code> has been called, but the module doesn't show any signs of ever being reloaded with <code>define</code> available to it. How can I achieve that?</p>
  
  <p>And is there a safe way of nullifying <code>module</code> so that I can test the browser condition as well?</p>