浅析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 相关文章推荐
几种延迟加载JS代码的方法加快网页的访问速度
Oct 12 Javascript
JavaScript中双叹号(!!)作用示例介绍
Apr 10 Javascript
JavaScript实现的in_array函数
Aug 27 Javascript
深入理解JavaScript系列(19):求值策略(Evaluation strategy)详解
Mar 05 Javascript
javascript中判断json的方法总结
Aug 27 Javascript
不定义JQuery插件 不要说会JQuery
Mar 07 Javascript
浅析Javascript ES6新增值比较函数Object.is
Aug 24 Javascript
Bootstrap如何激活导航状态
Mar 22 Javascript
微信小程序开发之animation循环动画实现的让云朵飘效果
Jul 14 Javascript
vue打包的时候自动将px转成rem的操作方法
Jun 20 Javascript
解决angularjs service中依赖注入$scope报错的问题
Oct 02 Javascript
Vue通过懒加载提升页面响应速度
May 10 Vue.js
浅析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
php4的session功能评述(三)
2006/10/09 PHP
PHP容易忘记的知识点分享
2013/04/30 PHP
php无限遍历文件夹示例分享
2014/03/04 PHP
php爬取天猫和淘宝商品数据
2018/02/23 PHP
javascript之ESC(第二类混淆)
2007/05/06 Javascript
javascript 页面只自动刷新一次
2009/07/10 Javascript
左侧是表头的JS表格控件(自写,网上没有的)
2013/06/04 Javascript
Bootstrap学习笔记之css样式设计(2)
2016/06/07 Javascript
原生js仿jquery一些常用方法(必看篇)
2016/09/20 Javascript
微信小程序 wx.request(object) API详解及实例代码
2016/09/30 Javascript
jQuery插件jqGrid动态获取列和列字段的方法
2017/03/03 Javascript
Require.JS中的几种define定义方式示例
2017/06/01 Javascript
微信小程序开发之map地图实现教程
2017/06/08 Javascript
在Vue组件上动态添加和删除属性方法
2018/02/23 Javascript
Vue瀑布流插件的使用示例
2018/09/19 Javascript
Vue 组件封装 并使用 NPM 发布的教程
2018/09/30 Javascript
微信小程序公用参数与公用方法用法示例
2019/01/09 Javascript
vue实现下拉加载其实没那么复杂
2019/08/13 Javascript
使用Vant完成DatetimePicker 日期的选择器操作
2020/11/12 Javascript
python抓取网页内容示例分享
2014/02/24 Python
python基于windows平台锁定键盘输入的方法
2015/03/05 Python
Python中random模块生成随机数详解
2016/03/10 Python
理论讲解python多进程并发编程
2018/02/09 Python
在pandas多重索引multiIndex中选定指定索引的行方法
2018/11/16 Python
TensorFlow2.X结合OpenCV 实现手势识别功能
2020/04/08 Python
Python性能分析工具py-spy原理用法解析
2020/07/27 Python
利用Python实现自动扫雷小脚本
2020/12/17 Python
Python 虚拟环境工作原理解析
2020/12/24 Python
python使用scapy模块实现ping扫描的过程详解
2021/01/21 Python
利用CSS3参考手册和CSS3代码生成工具加速来学习网页制
2012/07/11 HTML / CSS
HTML5 本地存储 LocalStorage详解
2016/06/24 HTML / CSS
心碎乌托邦的创业计划书范文
2013/12/26 职场文书
关于爱情的广播稿
2014/01/16 职场文书
房屋买卖协议书范本
2014/09/27 职场文书
2015年银行员工工作总结
2015/04/24 职场文书
初中语文教学反思范文
2016/03/03 职场文书