Skip to content

Instantly share code, notes, and snippets.

@michaelenger
Created October 30, 2014 14:10
Show Gist options
  • Save michaelenger/587194d6b42bdbd7ccd2 to your computer and use it in GitHub Desktop.
Save michaelenger/587194d6b42bdbd7ccd2 to your computer and use it in GitHub Desktop.
Dependency injection in node
/**
* Loads a module with the means to inject mocks.
* Usage:
* module = require('module-name'); // old and busted
* module = loadModule('/path/to/module-name.js', { // new hotness
* 'mocked-module-name': {}
* });
*
* Thanks to: http://howtonode.org/testing-private-state-and-mocking-deps
*
* @param {string} filePath Path to the module (must be absolute path to module file)
* @param {object} mocks Mocks to inject
* @return {object} Module
*/
loadModule = function (filePath, mocks) {
var exports = {},
context,
/**
* Resolve the module path, allowing for paths relative to the current module.
*
* @param {string} module Path to the module
* @return {string}
*/
resolveModule = function (module) {
if (module.charAt(0) !== '.') {
return module;
}
return path.resolve(path.dirname(filePath), module);
},
/**
* Require a module, replacing the real one with a mock if it exists.
*
* @param {string} module Path to the module
*/
requireModule = function (module) {
var name = path.basename(module, '.js');
return mocks[name] || require(resolveModule(module));
};
mocks = mocks || {};
context = {
require: requireModule,
console: console,
exports: exports,
module: {
exports: exports
}
};
vm.runInNewContext(fs.readFileSync(filePath), context);
return context.module.exports;
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment