-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 360ef9b
Showing
63 changed files
with
7,438 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Original file line | Diff line number | Diff line change |
---|---|---|---|
@@ -0,0 +1,42 @@ | |||
Syringe | |||
======= | |||
Using modules in node is easy however unit testing code that requires modules is a little more tricky. Syringe aims to assist with this problem by providing a handy set of helpers for injection and watching of module methods. | |||
|
|||
## Turtles all the way down | |||
To properly unit test your code you need mock all the modules and methods your module collaborates with. Ideally you keep going till you hit turtles or at least until you've stubbed every method you use. Take the following example: | |||
|
|||
var dns = require('dns'); | |||
var url = require('url'); | |||
|
|||
module.exports.resolveAddress = function(urlToResolve, callback) { | |||
var urlParsed = url.parse(urlToResolve).hostname; | |||
|
|||
dns.resolve4(urlParsed, callback); | |||
}; | |||
|
|||
In order to unit test this module properly, you need to mock functions in the dns and url modules. Syringe lets you inject directly over the top of modules or selectively mock the methods in them you're using. | |||
|
|||
var dns = require('./dns'); | |||
var syringe = require('syringe'); | |||
|
|||
var dnsMod = syringe('dns'); | |||
var urlMod = syringe('url'); | |||
|
|||
dnsMod.inject('resolve4', function (url, callback) { | |||
callback(null, ['127.0.0.1']); | |||
}); | |||
|
|||
urlMod.inject('parse', function() { | |||
return {hostname: 'www.google.com'}; | |||
}); | |||
|
|||
urlMod.wrap('parse', function() { | |||
console.log('yep, that function was called from within the require!'); | |||
}); | |||
|
|||
dns.resolveAddress('http://www.google.com/', function(err, result) { | |||
if (err) { | |||
throw new Error(err); | |||
} | |||
console.log('Resolved dns list:', result); | |||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Original file line | Diff line number | Diff line change |
---|---|---|---|
@@ -0,0 +1,8 @@ | |||
var dns = require('dns'); | |||
var url = require('url'); | |||
|
|||
module.exports.resolveAddress = function(urlToResolve, callback) { | |||
var urlParsed = url.parse(urlToResolve).hostname; | |||
|
|||
dns.resolve4(urlParsed, callback); | |||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Original file line | Diff line number | Diff line change |
---|---|---|---|
@@ -0,0 +1,23 @@ | |||
var dns = require('./dns'); | |||
var syringe = require('../lib/syringe'); | |||
var dnsMod = syringe('dns'); | |||
var urlMod = syringe('url'); | |||
|
|||
dnsMod.inject('resolve4', function (url, callback) { | |||
callback(null, ['127.0.0.1']); | |||
}); | |||
|
|||
urlMod.inject('parse', function() { | |||
return {hostname: 'www.google.com'}; | |||
}); | |||
|
|||
urlMod.wrap('parse', function() { | |||
console.log('yep, that function was called from within the require!'); | |||
}); | |||
|
|||
dns.resolveAddress('http://www.google.com/', function(err, result) { | |||
if (err) { | |||
throw new Error(err); | |||
} | |||
console.log('Resolved dns list:', result); | |||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Original file line | Diff line number | Diff line change |
---|---|---|---|
@@ -0,0 +1 @@ | |||
module.exports = require('./lib/syringe'); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Original file line | Diff line number | Diff line change |
---|---|---|---|
@@ -0,0 +1,75 @@ | |||
var modules = {}; | |||
|
|||
function Syringe(moduleName) { | |||
var moduleCache = {}, | |||
module = require(moduleName); | |||
|
|||
modules[moduleName] = module; | |||
|
|||
this.inject = function(methodName, method) { | |||
if(module[methodName]) { | |||
this.forceInject(methodName, method); | |||
return this; | |||
} else { | |||
throw new Error(methodName + ' does not exist in the module.'); | |||
} | |||
}; | |||
|
|||
this.forceInject = function(methodName, method) { | |||
if(module[methodName]) { | |||
moduleCache[methodName] = module[methodName]; | |||
} | |||
module[methodName] = method; | |||
return this; | |||
}; | |||
|
|||
this.restore = function(methodName) { | |||
if(moduleCache[methodName]) { | |||
module[methodName] = moduleCache[methodName]; | |||
return this; | |||
} else { | |||
throw new Error(methodName + ' does not exist in the module so cannot be restored.'); | |||
} | |||
}; | |||
|
|||
this.wrap = function(methodName, before) { | |||
if (module[methodName] && typeof before === 'function') { | |||
moduleCache[methodName] = module[methodName]; | |||
|
|||
module[methodName] = function() { | |||
before(); | |||
return moduleCache[methodName].apply(null, arguments); | |||
} | |||
} else { | |||
throw new Error(methodName + ' does not exist in the module so cannot be wrapped.'); | |||
} | |||
}; | |||
|
|||
this.unWrap = function(methodName) { | |||
this.restore(methodName); | |||
}; | |||
|
|||
this.replaceAll = function(replaceModule) { | |||
if (typeof replaceModule === 'object') { | |||
for(var methodName in replaceModule) { | |||
this.inject(methodName, replaceModule[methodName]); | |||
} | |||
} else { | |||
throw new Error(methodName + ' does not exist in the module so cannot be wrapped.'); | |||
} | |||
}; | |||
|
|||
this.restoreAll = function(restoreModule) { | |||
for(var method in moduleCache) { | |||
this.restore(method); | |||
}; | |||
}; | |||
} | |||
|
|||
module.exports = function(moduleName) { | |||
if (!modules[moduleName]) { | |||
return new Syringe(moduleName); | |||
} else { | |||
return modules[moduleName]; | |||
} | |||
}; |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
Oops, something went wrong.