I've created this (very) contrived example that demonstrates how we currently organize page specific JS in our app. Basically each page has a matching JS file that uses the module pattern to enclose page specific behaviors. Each module has an init()
function that takes control IDs and wires up events, etc.
This has worked fairely well for us, however now we are wanting to add unit tests. Since many of our modules store state in private variables our unit tests end up stomping all over each other.
I think we need to stop using these singleton modules and instead use instances so that we can write better tests. What are some ways we could restructure this type of code so that it would be testable?
HTML
<div>
<input type="file" /><br/>
<input type="file" /><br/>
<input type="file" />
</div>
<p>
<br/>
<input id="btnUpload" type="button" value="Upload Files" />
or <a href="#" id="btnClear">Clear files</a>
</p>
<script>
MyPage.init({
clearLink: '#btnClear',
uploadBtn: '#btnUpload',
fileCtrls: "input[type='file']"
});
</script>
JS
MyPage = (function() {
// private members
var _files = [];
var _initOptions;
// public members
return {
init: function(options) {
_initOptions = options;
$(function() {
// wire up the events
$(options.clearLink).click(MyPage.clear);
$(options.uploadBtn).click(MyPage.doUpload);
$(options.fileCtrls).change(MyPage.addFile);
});
},
addFile: function() {
_files.push($(this).val());
},
doUpload: function() {
alert('uploading ' + _files.length + ' files...');
},
clear: function() {
_files = [];
$(_initOptions.fileCtrls).val('');
}
}
})();