浅析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 相关文章推荐
jquery BS,dialog控件自适应大小
Jul 06 Javascript
减少访问DOM的次数提升javascript性能
Feb 24 Javascript
用js设置下拉框为只读的小技巧
Apr 10 Javascript
jQuery横向擦除焦点图特效代码分享
Sep 06 Javascript
jquery在ie7下选择器的问题导致append失效的解决方法
Jan 10 Javascript
jquery实现ajax加载超时提示的方法
Jul 23 Javascript
mvc中form表单提交的三种方式(推荐)
Aug 10 Javascript
原生js图片轮播效果实现代码
Oct 19 Javascript
Vue使用NPM方式搭建项目
Oct 25 Javascript
微信小程序如何访问公众号文章
Jul 08 Javascript
浅谈JS中几种轻松处理'this'指向方式
Sep 16 Javascript
原生js实现贪吃蛇游戏
Oct 26 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
关于Appserv无法打开localhost问题的解决方法
2009/10/16 PHP
PHP常用技巧总结(附函数代码)
2012/02/04 PHP
php中使用preg_match_all匹配文章中的图片
2013/02/06 PHP
php中文验证码实现方法
2015/06/18 PHP
PHP缓冲区用法总结
2016/02/14 PHP
PHP使用星号隐藏用户名,手机和邮箱的实现方法
2016/09/22 PHP
thinkPHP框架实现的简单计算器示例
2018/12/07 PHP
针对PHP开发安全问题的相关总结
2019/03/22 PHP
PHP程序员简单的开展服务治理架构操作详解(一)
2020/05/14 PHP
JavaScript窗口功能指南之在窗口中书写内容
2006/07/21 Javascript
利用js实现遮罩以及弹出可移动登录窗口
2013/07/08 Javascript
JavaScript立即执行函数的三种不同写法
2014/09/05 Javascript
jQuery中append()方法用法实例
2014/12/25 Javascript
javascript 秒表计时器实现代码
2017/03/09 Javascript
简单谈谈关于Angular Cli打包的事
2017/09/05 Javascript
vue自定义表单生成器form-create使用详解
2019/07/19 Javascript
使用PYTHON接收多播数据的代码
2012/03/01 Python
python简单的函数定义和用法实例
2015/05/07 Python
python获得文件创建时间和修改时间的方法
2015/06/30 Python
对python dataframe逻辑取值的方法详解
2019/01/30 Python
Python logging模块handlers用法详解
2020/08/14 Python
Python实现迪杰斯特拉算法并生成最短路径的示例代码
2020/12/01 Python
详解canvas在圆弧周围绘制文本的两种写法
2018/05/22 HTML / CSS
处理HTML5新标签的浏览器兼容版问题
2017/03/13 HTML / CSS
夏尔巴人登珠峰品牌:Sherpa Adventure Gear
2018/02/08 全球购物
Dower & Hall官网:英国小众轻奢珠宝品牌
2019/01/31 全球购物
机电一体化毕业生求职信
2013/11/02 职场文书
一份创业计划书范文
2014/02/08 职场文书
《和田的维吾尔》教学反思
2014/04/14 职场文书
学生会竞选演讲稿怎么写
2014/08/26 职场文书
租房协议书范例
2014/10/14 职场文书
2014年人民调解工作总结
2014/12/08 职场文书
五好文明家庭事迹材料
2014/12/20 职场文书
初二物理教学反思
2016/02/19 职场文书
七年级之家长会发言稿范文
2019/09/04 职场文书
Maven学习----Maven安装与环境变量配置教程
2021/06/29 Java/Android