浅析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表单验证代码
Aug 02 Javascript
从阶乘函数对比Javascript和C#的异同
May 31 Javascript
Jquery判断$("#id")获取的对象是否存在的方法
Sep 25 Javascript
JS、CSS加载中的小问题探讨
Nov 26 Javascript
javascript中的正则表达式使用指南
Mar 01 Javascript
原生node.js案例--前后台交互
Feb 20 Javascript
jquery 禁止鼠标右键并监听右键事件
Apr 27 jQuery
JavaScript数组去重算法实例小结
May 07 Javascript
JavaScript 下载svg图片为png格式
Jun 21 Javascript
React Native基础入门之调试React Native应用的一小步
Jul 02 Javascript
浅析Proxy可以优化vue的数据监听机制问题及实现思路
Nov 29 Javascript
JS异步宏队列微队列原理详解
Sep 09 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
合作指挥官:孟斯克
2020/03/16 星际争霸
PHP表单验证的3个函数ISSET()、empty()、is_numeric()的使用方法
2011/08/22 PHP
PHP技术开发微信公众平台
2015/07/22 PHP
thinkPHP使用pclzip打包备份mysql数据库的方法
2016/04/30 PHP
php表单加入Token防止重复提交的方法分析
2016/10/10 PHP
thinkphp5.1 文件引入路径问题及注意事项
2018/06/13 PHP
php实现将数据做成json的格式给前端使用
2018/08/21 PHP
Thinkphp 3.2框架使用Redis的方法详解
2019/10/24 PHP
JAVASCRIPT 对象的创建与使用
2021/03/09 Javascript
jquery 弹出层实现代码
2009/10/30 Javascript
jquery validator 插件增加日期比较方法
2010/02/21 Javascript
javascript检测页面是否缩放的小例子
2013/05/16 Javascript
用JS做的简单的可折叠的两级树形菜单
2013/09/21 Javascript
js中的时间转换—毫秒转换成日期时间的示例代码
2014/01/26 Javascript
用jQuery与JSONP轻松解决跨域访问的问题
2014/02/04 Javascript
详解javascript跨浏览器事件处理程序
2016/03/27 Javascript
js实现一键复制功能
2017/03/16 Javascript
微信小程序实战篇之购物车的实现代码示例
2017/11/30 Javascript
基于vue 添加axios组件,解决post传参数为null的问题
2018/03/05 Javascript
vue自动添加浏览器兼容前后缀操作
2020/08/13 Javascript
python机器学习之神经网络(一)
2017/12/20 Python
Python实现的rsa加密算法详解
2018/01/24 Python
解决python matplotlib imshow无法显示的问题
2018/05/24 Python
Python 硬币兑换问题
2019/07/29 Python
python 数据提取及拆分的实现代码
2019/08/26 Python
Python常用模块os.path之文件及路径操作方法
2019/12/03 Python
python字符串下标与切片及使用方法
2020/02/13 Python
在python中使用pyspark读写Hive数据操作
2020/06/06 Python
让IE支持CSS3的不完全兼容方案
2014/09/19 HTML / CSS
Ego Shoes官网:英国时髦鞋类品牌
2020/10/19 全球购物
测试时代收集的软件测试面试题
2013/09/25 面试题
社区党的群众路线教育实践活动总结材料
2014/10/31 职场文书
公司表扬稿范文
2015/05/05 职场文书
2016年中秋节晚会领导致辞
2015/11/26 职场文书
python爬虫之selenium库的安装及使用教程
2021/05/23 Python
win10电脑右下角输入法图标不见了?Win10右下角不显示输入法的解决方法
2022/07/23 数码科技