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


Posted in Javascript onJune 24, 2015

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

requireCauses 问题

Node.js很容易依照需求导入依赖。它运行的很好,并且比AMD模式加载器例如RequireJS要简单。当我们模拟那些依赖的时候问题就来了。如果Node.js中模型的加载是受控的,我们怎么做才能控制让伪对象在测试期间被使用到?我们可以使用Node的vm模式,通过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;
};

你也可以在 这里 下载代码片段 . 虽然在不是在文章发布最多的代码, 他仍然可以使用一些解释. 当我们测试时, 我们要加载这个模块进入测试, 使用theloadModulefunction代替ofrequire加载模块测试.
 
第一个参数filePath指定了我们要测试模型的查找位置。第二个参数mocks包含一个对象,对象的属性名称要和我们尝试require的模型的名称相匹配。那些属性指定的值就是伪对象,用来代替一般被require的模型。

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

使用模块加载器的例子

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

var fs = require('fs');
 
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 相关文章推荐
javascript 类方法定义还是有点区别
Apr 15 Javascript
jquery控制显示服务器生成的图片流
Aug 04 Javascript
jQuery中的通配符选择器使用总结
May 30 Javascript
js正则表达式最长匹配(贪婪匹配)和最短匹配(懒惰匹配)用法分析
Dec 27 Javascript
React创建组件的三种方式及其区别
Jan 12 Javascript
xmlplus组件设计系列之路由(ViewStack)(7)
May 02 Javascript
xmlplus组件设计系列之网格(DataGrid)(10)
May 05 Javascript
webpack处理 css\less\sass 样式的方法
Aug 21 Javascript
node.js使用redis储存session的方法
Sep 26 Javascript
javascript异步编程的六种方式总结
May 17 Javascript
CKEditor 4.4.1 添加代码高亮显示插件功能教程【使用官方推荐Code Snippet插件】
Jun 14 Javascript
JS多个表单数据提交下的serialize()应用实例分析
Aug 27 Javascript
浅析Node.js中的内存泄漏问题
Jun 23 #Javascript
充分发挥Node.js程序性能的一些方法介绍
Jun 23 #Javascript
Node.js编程中客户端Session的使用详解
Jun 23 #Javascript
使用Meteor配合Node.js编写实时聊天应用的范例
Jun 23 #Javascript
使用Node.js为其他程序编写扩展的基本方法
Jun 23 #Javascript
Windows系统下Node.js的简单入门教程
Jun 23 #Javascript
jQuery实现判断滚动条到底部
Jun 23 #Javascript
You might like
PHP与MySQL开发的8个技巧小结
2010/12/17 PHP
深入理解PHP之require/include顺序 推荐
2011/01/02 PHP
php文件缓存类汇总
2014/11/21 PHP
combox改进版 页面原型参考dojo的,比网上jQuery的那些combox功能强,代码更小
2010/04/15 Javascript
JavaScript中的getTime()方法使用详解
2015/06/10 Javascript
微信小程序自定义导航隐藏和显示功能
2017/06/13 Javascript
你可能不知道的JSON.stringify()详解
2017/08/17 Javascript
Vue.js在数组中插入重复数据的实现代码
2017/11/17 Javascript
jQuery时间戳和日期相互转换操作示例
2018/12/07 jQuery
JavaScript数组特性与实践应用深入详解
2018/12/30 Javascript
js form表单input框限制20个字符,10个汉字代码实例
2019/04/12 Javascript
Vue scrollBehavior 滚动行为实现后退页面显示在上次浏览的位置
2019/05/27 Javascript
js实现数字滚动特效
2019/12/16 Javascript
Python搭建HTTP服务器和FTP服务器
2017/03/09 Python
Unicode和Python的中文处理
2017/03/19 Python
Python实现通讯录功能
2018/02/22 Python
python实现音乐下载器
2018/04/15 Python
python存储16bit和32bit图像的实例
2018/12/05 Python
强悍的Python读取大文件的解决方案
2019/02/16 Python
python opencv将表格图片按照表格框线分割和识别
2019/10/30 Python
python爬虫多次请求超时的几种重试方法(6种)
2020/12/01 Python
Sneaker Studio乌克兰:购买运动鞋
2018/03/26 全球购物
小米官方旗舰店:Xiaomi
2020/08/07 全球购物
Java中各种基本数据类型的默认值都是什么
2016/12/22 面试题
酒店餐厅2014重阳节活动策划方案
2014/09/16 职场文书
标准大学生职业生涯规划书写作指南
2014/09/18 职场文书
2014年光棍节活动策划方案(创意集锦)
2014/09/29 职场文书
单位作风建设剖析材料
2014/10/11 职场文书
老乡聚会通知
2015/04/23 职场文书
2015年司机年终工作总结
2015/05/14 职场文书
新闻通讯稿模板
2015/07/22 职场文书
小学运动会报道稿
2015/07/22 职场文书
2015年国庆节演讲稿范文
2015/07/30 职场文书
2016年党风廉政建设承诺书
2016/03/25 职场文书
Apache Calcite 实现方言转换的代码
2021/04/24 Servers
Win10防火墙白名单怎么设置?Win10添加防火墙白名单方法
2022/04/06 数码科技