浅析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 相关文章推荐
Yii-自定义删除确认弹框(zyd)jquery实现代码
Mar 04 Javascript
javascript中的document.open()方法使用介绍
Oct 09 Javascript
jquery实现点击查看更多内容控制段落文字展开折叠效果
Aug 06 Javascript
JavaScript继承模式粗探
Jan 12 Javascript
Hallo.js基于jQuery UI所见即所得的Web编辑器
Jan 26 Javascript
深入理解JavaScript中的call、apply、bind方法的区别
May 30 Javascript
js实现一个猜数字游戏
Mar 31 Javascript
Vue.js tab实现选项卡切换
May 16 Javascript
vue中使用refs定位dom出现undefined的解决方法
Dec 21 Javascript
p5.js 毕达哥拉斯树的实现代码
Mar 23 Javascript
JS实现可视化文件上传
Sep 08 Javascript
jquery中attr、prop、data区别与用法分析
Sep 25 jQuery
浅析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 文件状态缓存带来的问题
2008/12/14 PHP
一些php技巧与注意事项分析
2011/02/03 PHP
php数组函数序列之in_array() 查找数组值是否存在
2011/10/29 PHP
浅析echo(),print(),print_r(),return之间的区别
2013/11/27 PHP
codeigniter框架批量插入数据
2014/01/09 PHP
PHP防范SQL注入的具体方法详解(测试通过)
2014/05/09 PHP
PHP实现将视频转成MP4并获取视频预览图的方法
2015/03/12 PHP
PHP简单实现HTTP和HTTPS跨域共享session解决办法
2015/05/27 PHP
php7 图形用户界面GUI 开发示例
2020/02/22 PHP
一些常用的JS功能函数代码
2009/06/23 Javascript
一个js的tab切换效果代码[代码分离]
2010/04/11 Javascript
js批量设置样式的三种方法不推荐使用with
2013/02/25 Javascript
jQuery实现优雅的弹窗效果(6)
2017/02/08 Javascript
Javascript网页抢红包外挂实现分享
2018/01/11 Javascript
vue实现在一个方法执行完后执行另一个方法的示例
2018/08/25 Javascript
基于vue v-for 多层循环嵌套获取行数的方法
2018/09/26 Javascript
[23:18]Spirit vs Liquid Supermajor小组赛A组 BO3 第二场 6.2
2018/06/03 DOTA
[01:02:47]EG vs Secret 2019国际邀请赛淘汰赛 胜者组 BO3 第一场 8.21.mp4
2020/07/19 DOTA
python类定义的讲解
2013/11/01 Python
Python实现网络端口转发和重定向的方法
2016/09/19 Python
Python numpy实现数组合并实例(vstack,hstack)
2018/01/09 Python
Python unittest模块用法实例分析
2018/05/25 Python
Python实现的特征提取操作示例
2018/12/03 Python
python flask搭建web应用教程
2019/11/19 Python
浅谈在JupyterNotebook下导入自己的模块的问题
2020/04/16 Python
Python turtle库的画笔控制说明
2020/06/28 Python
python使用正则表达式匹配txt特定字符串(有换行)
2020/12/09 Python
用CSS3和table标签实现一个圆形轨迹的动画的示例代码
2019/01/17 HTML / CSS
HTML5使用drawImage()方法绘制图像
2014/06/23 HTML / CSS
夏洛特和乔治婴儿和儿童时装精品店:Charlotte and George
2018/06/06 全球购物
Brother加拿大官网:打印机、贴标机、缝纫机
2019/10/09 全球购物
英国百年闻名的优质健康产品连锁店:Holland & Barrett
2019/12/19 全球购物
编码实现字符串转整型的函数
2012/06/02 面试题
应用艺术毕业生的自我评价
2013/12/04 职场文书
小学生操行评语
2014/04/22 职场文书
测量JavaScript函数的性能各种方式对比
2021/04/27 Javascript