浅析Node.js中使用依赖注入的相关问题及解决方法

前端之家收集整理的这篇文章主要介绍了浅析Node.js中使用依赖注入的相关问题及解决方法前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

最近,我转向使用来帮助理解分离代码的简单途径,并有助测试。然而,Node.js中的模块依赖Node提供的系统API,这很难判断私有依赖被恰当的使用。一般的依赖注入很难在这种情况下使用,但现在不要放弃希望。

requireCauses 问题

Node.js很容易依照需求导入依赖。它运行的很好,并且比AMD模式加载器例如RequireJS要简单。当我们模拟那些依赖的时候问题就来了。如果Node.js中模型的加载是受控的,我们怎么做才能控制让伪对象在测试期间被使用到?我们可以使用Node的vm模式,通过vm我们可以再新的上下文中加载模型。运行在新的上下文中,我们可以控制需求反射出模型的方法。

解决方案

谢谢这篇文章,现在可以给你提供一个相当不错的解决方案. 代码在下面:

/**

  • 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;
};

你也可以在 下载代码片段 . 虽然在不是在文章发布最多的代码,他仍然可以使用一些解释. 当我们测试时,我们要加载这个模块进入测试,使用theloadModulefunction代替ofrequire加载模块测试.

第一个参数filePath指定了我们要测试模型的查找位置。第二个参数mocks包含一个对象,对象的属性名称要和我们尝试require的模型的名称相匹配。那些属性指定的值就是伪对象,用来代替一般被require的模型。

本质上看就是用vm来加载和运行模型在另一个“上下文”中。换句话说,我们重建了全局变量(例如require和exports)以便我们能控制它们。需要注意的是我们编写了一个可用的新require函数。所做一切就是检查一下用执行的名字是否有一个模拟的依赖,如果每日有,我就就把它委托给那个常用的require函数

使用模块加载器的例子

如果你还有点困惑,你可以看下面的代码示例,看它在上下文中的使用,也许能帮你清楚一些。首先,我们创建一个简单的模块。

module.exports = {
// Do something with fs
}
想象一下这个很酷,对吗?不管怎样,现在我们测试那个模块,但是我们要模拟fs来看看它是怎么在内部使用的。

// Jasmine's Syntax http://pivotal.github.com/jasmine/
describe('someModule',function() {
var loadModule = require('module-loader').loadModule;
var module,fsMock;

beforeEach(function() {
fsMock = {
// a mock for fs
};

// load the module with mock fs instead of real fs
module = loadModule('./web-server.js',{fs: fsMock});
});

it('should work',function() {
// a test that utilizes the fact that we can now control fs
});
});

主要注意是在7至12行,我们为fs创建了一个伪对象并使用我们新的loadModule函数将这个使用的对象联系到上面的小模块中(我的意思是真棒!请记住,这是真棒,对不对?)。

猜你在找的JavaScript相关文章