Skip to content

Instantly share code, notes, and snippets.

@tkissing
Last active February 12, 2019 03:41
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tkissing/e5fa4908150c82d73131 to your computer and use it in GitHub Desktop.
Save tkissing/e5fa4908150c82d73131 to your computer and use it in GitHub Desktop.
Singleton JavaScript modules that are easy to test! (Hint: Avoid object literals)
// using AMD syntax here to avoid confusion about scope and file boundaries,
// but the concept translates 1:1 to CommonJS (node/io) modules
define('badSingleton', function(require, exports, module) {
var dependency = require('dependency');
var privateState;
module.exports = {
foo: function() {
return privateState;
},
bar: function() {
privateState = dependency(privateState ? 'bar': 'baz');
},
baz: function() {
if (privateState) {
return Promise.resolve(privateState);
}
return Promise.reject();
}
}
});
// once you call .bar, there is no way to reset the internal state of badSingleton.
// The order of your unit tests now matters!
// also, mocking dependency is non-trivial in both node and the browser
define('betterSingleton', function(require, exports, module) {
var dependency = require('dependency');
function BetterSingleton(dependency) {
// move ALL the state inside the constructor
var privateState;
this.foo = function() {
return privateState;
};
this.bar = function() {
privateState = dependency(privateState ? 'bar': 'baz');
};
this.baz = function() {
if (privateState) {
return Promise.resolve(privateState);
}
return Promise.reject();
}
}
module.exports = new BetterSingleton(dependency);
});
// now in your tests you can write
// var BetterSingletonConstructor = require('betterSingleton').constructor;
// and create as many instances as you have tests, each starting with a clean state.
// and since we moved the dependency into a constructor argument
// the tests can make it with ease if needed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment