----------- 更新 ---------------
node-sandbox 的工作原理与下文所述相同,但包含在一个不错的模块中。我发现它非常适合使用。
--------------- 详细的遮阳篷 ---------------
经过多次试验,我发现在模拟事物的同时单独测试节点模块的最佳方法是使用 Vojta Jina 的方法在具有新上下文的虚拟机内运行每个模块,如 here 所述。
使用这个测试 vm 模块:
var vm = require('vm');
var fs = require('fs');
var path = require('path');
/**
* Helper for unit testing:
* - load module with mocked dependencies
* - allow accessing private state of the module
*
* @param {string} filePath Absolute path to module (file to load)
* @param {Object=} mocks Hash of mocked dependencies
*/
exports.loadModule = function(filePath, mocks) {
mocks = mocks || {};
// this is necessary to allow relative path modules within loaded file
// i.e. requiring ./some inside file /a/b.js needs to be resolved to /a/some
var resolveModule = function(module) {
if (module.charAt(0) !== '.') return module;
return path.resolve(path.dirname(filePath), module);
};
var exports = {};
var context = {
require: function(name) {
return mocks[name] || require(resolveModule(name));
},
console: console,
exports: exports,
module: {
exports: exports
}
};
vm.runInNewContext(fs.readFileSync(filePath), context);
return context;
};
可以使用自己的上下文测试每个模块,并轻松排除所有外部依赖项。
fsMock = mocks.createFs();
mockRequest = mocks.createRequest();
mockResponse = mocks.createResponse();
// load the module with mock fs instead of real fs
// publish all the private state as an object
module = loadModule('./web-server.js', {fs: fsMock});
我强烈推荐这种方式来单独编写有效的测试。只有验收测试才能触及整个堆栈。单元和集成测试应该测试系统的独立部分。