浅析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 06 Javascript
JS操作Cookies包括(读取添加与删除)
Dec 26 Javascript
Javascript函数式编程简单介绍
Oct 11 Javascript
自己动手写的javascript前端等待控件
Oct 30 Javascript
基于javascript实现tab选项卡切换特效调试笔记
Mar 30 Javascript
基于CSS3和jQuery实现跟随鼠标方位的Hover特效
Jul 25 Javascript
jQuery实现简单的tab标签页效果
Sep 12 Javascript
微信小程序实现传参数的几种方法示例
Jan 10 Javascript
layui的表单验证支持ajax判断用户名是否重复的实例
Sep 06 Javascript
基于vue+uniapp直播项目实现uni-app仿抖音/陌陌直播室功能
Nov 12 Javascript
JavaScript实现简易聊天对话框(加滚动条)
Feb 10 Javascript
如何使用Javascript中的this关键字
May 28 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
discuz加密解密函数使用方法和中文注释
2014/01/21 PHP
php字符串操作针对负值的判断分析
2016/07/28 PHP
JavaScript脚本性能优化注意事项
2008/11/18 Javascript
php图像生成函数之间的区别分析
2012/12/06 Javascript
form表单只提交数据而不进行页面跳转的解决方案
2013/09/18 Javascript
JQuery中使用Ajax赋值给全局变量异常的解决方法
2014/01/10 Javascript
arguments对象验证函数的参数是否合法
2015/06/26 Javascript
JS实现弹性漂浮效果的广告代码
2015/09/02 Javascript
基于javascript代码检测访问网页的浏览器呈现引擎、平台、Windows操作系统、移动设备和游戏系统
2015/12/03 Javascript
AngularJS入门教程之AngularJS模型
2016/04/18 Javascript
用JS实现图片轮播效果代码(一)
2016/06/26 Javascript
使用 jQuery.ajax 上传带文件的表单遇到的问题
2016/10/31 Javascript
微信小程序开发之相册选择和拍照详解及实例代码
2017/02/22 Javascript
jQuery选择器特殊字符与属性空格问题
2017/08/14 jQuery
详解浏览器缓存和webpack缓存配置
2018/07/06 Javascript
微信小程序12行js代码自己写个滑块功能(推荐)
2020/07/15 Javascript
解决vue.js中settimeout遇到的问题(时间参数短效果不稳定)
2020/07/21 Javascript
[48:38]DOTA2亚洲邀请赛 3.31 小组赛 B组 Mineski vs Secret
2018/03/31 DOTA
使用python和Django完成博客数据库的迁移方法
2018/01/05 Python
Python的numpy库中将矩阵转换为列表等函数的方法
2018/04/04 Python
使用Python实现一个栈判断括号是否平衡
2018/08/23 Python
浅谈python实现Google翻译PDF,解决换行的问题
2018/11/28 Python
python移位运算的实现
2019/07/15 Python
使用selenium和pyquery爬取京东商品列表过程解析
2019/08/15 Python
Python3 使用selenium插件爬取苏宁商家联系电话
2019/12/23 Python
Python astype(np.float)函数使用方法解析
2020/06/08 Python
python中xlrd模块的使用详解
2021/02/01 Python
解决Pyinstaller打包软件失败的一个坑
2021/03/04 Python
在html5的Canvas上绘制椭圆的几种方法总结
2013/01/07 HTML / CSS
德国高品质男装及配饰商城:Cultizm(Raw Denim原色牛仔裤)
2018/04/16 全球购物
成龙洗发水广告词
2014/03/14 职场文书
文案策划专业自荐信
2014/07/07 职场文书
学校食堂食品安全责任书
2014/07/28 职场文书
2014年检察院个人工作总结
2014/12/09 职场文书
保险公司客户经理岗位职责
2015/04/09 职场文书
导游词之秦始皇兵马俑博物馆
2019/09/29 职场文书