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 privateVar
is correctly set during the callback of the $.getJSON
ajax request.
The second test it('should update privateVar', ...),
doesn't work because myModule.privateVar
is (intentionally) not in the public api for the module.
So, my question is, What is the best way to test this kind of behaviour without having to make the privateVar part of the public api? 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?
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();
});
});
});
}
);
What you are talking about here unfortunately requires an integration test, you wish to test that a variable is set as a result of an external operation, You should trust that the external method just works for your test by stubbing it out in your tests as you have done with sinon this takes care of the external call.
What you need to be able to do is to control the conditions of the test (lets say non authenticated and authenticated) then test what the result of the function is in that instance. As a rule I don't normally test private members at all but I do test desired behaviour resulting from known good and bad values..
I also read this a little while ago, which discusses private vars.