浅析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与DropDownList 区别分析
Jan 01 Javascript
js function定义函数使用心得
Apr 15 Javascript
jquery实用代码片段集合
Aug 12 Javascript
js 判断脚本加载完毕的代码
Jul 13 Javascript
jQuery LigerUI 使用教程表格篇(1)
Jan 18 Javascript
jquery表单验证使用插件formValidator
Nov 10 Javascript
node.js中的url.resolve方法使用说明
Dec 10 Javascript
深入理解JavaScript系列(37):设计模式之享元模式详解
Mar 04 Javascript
javascript实现在网页任意处点左键弹出隐藏菜单的方法
May 13 Javascript
JavaScript多线程运行库Nexus.js详解
Dec 22 Javascript
Node.JS循环删除非空文件夹及子目录下的所有文件
Mar 12 Javascript
详解基于Vue cli生成的Vue项目的webpack4升级
Jun 19 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笔记之:日期函数的使用介绍
2013/04/24 PHP
使用php的HTTP请求的库Requests实现美女图片墙
2015/02/22 PHP
隐性调用php程序的方法
2015/06/13 PHP
PHP输出缓冲控制Output Control系列函数详解
2015/07/02 PHP
php for 循环使用的简单实例
2016/06/02 PHP
PHP使用递归算法无限遍历数组示例
2017/01/13 PHP
Yii框架扩展CGridView增加导出CSV功能的方法
2017/05/24 PHP
php上传图片并给图片打上透明水印的代码
2010/06/07 Javascript
jquery ajax abort()的使用方法
2010/10/28 Javascript
jquery下将选择的checkbox的id组成字符串的方法
2010/11/28 Javascript
jQuery实现统计复选框选中数量
2014/11/24 Javascript
JS实现Fisheye效果动感放大菜单代码
2015/10/21 Javascript
Node.js文件操作方法汇总
2016/03/22 Javascript
js 弹出虚拟键盘修改密码的简单实例
2016/10/10 Javascript
详解MVC如何使用开源分页插件(shenniu.pager.js)
2016/12/16 Javascript
基于Bootstrap的网页设计实例
2017/03/01 Javascript
Vue表单验证插件的制作过程
2017/04/01 Javascript
深入理解ES6中let和闭包
2018/02/22 Javascript
JS使用百度地图API自动获取地址和经纬度操作示例
2019/04/16 Javascript
使用xampp将angular项目运行在web服务器的教程
2019/09/16 Javascript
微信小程序request请求封装,验签代码实例
2019/12/04 Javascript
[03:15]2014DOTA2国际邀请赛 专访国士无双信心满满
2014/07/12 DOTA
[01:25]DOTA2自定义游戏灵园鬼域等你踏足
2015/10/30 DOTA
Python实现的飞速中文网小说下载脚本
2015/04/23 Python
Python检查ping终端的方法
2019/01/26 Python
python 自动轨迹绘制的实例代码
2019/07/05 Python
python实现桌面托盘气泡提示
2019/07/29 Python
Django框架 信号调度原理解析
2019/09/04 Python
Python的形参和实参使用方式
2019/12/24 Python
keras读取h5文件load_weights、load代码操作
2020/06/12 Python
python3爬虫中多线程进行解锁操作实例
2020/11/25 Python
Reebonz中国官网:新加坡奢侈品购物网站
2017/03/17 全球购物
365 Tickets英国:全球景点门票
2019/07/06 全球购物
儿科护士自我鉴定
2013/10/14 职场文书
给公司的建议书范文
2014/05/13 职场文书
少年的你:世界上没有如果,要在第一次就勇敢的反抗
2019/11/20 职场文书