title: Testing private members in Javascript using Sinon
body: <p>I'm starting to write some javascript tests and trying to figure out what the best approach is for inspecting the private members of a module constructor. For example, in the sample below i'm using the revealing module pattern to expose the public api to my module. I want to test that <code>privateVar</code> is correctly set during the callback of the <code>$.getJSON</code> ajax request.</p>
  
  <p>The second test <code>it('should update privateVar', ...),</code> doesn't work because <code>myModule.privateVar</code> is (intentionally) not in the public api for the module.</p>
  
  <p>So, my question is, <strong>What is the best way to test this kind of behaviour without having to make the privateVar part of the public api?</strong> Is there a better way to factor this code for testing, or maybe a way to use something like SinonJs to spy on the private member?</p>
  
  <pre><code>define('myModule',
      ['jquery'],
      function ($) {
          var
              myVar = "something",
              privateVar = "something else",
  
              doSomething = function() {
                  return $.getJSON('http://myapi.com/do-something', { requestData : "some data" }, function(response){
                      myVar = response.data.value1;
                      privateVar = response.data.value2;
                  });
              };
  
          return {
              doSomething : doSomething,
              myVar : myVar
          };
      }
  );
  
  define('test/test.myModule',
      ['myModule', 'chai', 'sinon', 'mocha'],
      function (myModule, chai, sinon) {
  
          describe("myModule", function() {
              var expect = chai.expect;
  
              describe('doSomething', function() {
  
                  var value1 = 'value1 value',
                      value2 = 'value2 value';
  
                  beforeEach(function() {
                      sinon.stub($, 'ajax').yieldsTo('success', {
                          data : { value1 : value1, value2 : value2 }
                      });
                  });
  
                  afterEach(function() {
                      $.ajax.restore();
                  });
  
                  it('should update myVar', function(done) {
                      myModule.doSomething();
                      expect(myModule.myVar).to.equal(value1);
                      done();
                  });
  
                  it('should update privateVar', function(done) {
                      myModule.doSomething();
                      expect(myModule.privateVar).to.equal(value2);
                      done();
                  });
              });
  
  
          });
  
      }
  );
  </code></pre>