浅析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监听表单value的修改同步问题,跨浏览器支持
Dec 31 Javascript
JavaScript 事件冒泡简介及应用
Jan 11 Javascript
js函数名与form表单元素同名冲突的问题
Mar 07 Javascript
基于jquery实现的可编辑下拉框实现代码
Aug 02 Javascript
jquery+html5制作超酷的圆盘时钟表
Apr 14 Javascript
jquery实现简单的遮罩层
Jan 08 Javascript
JavaScript+html5 canvas实现本地截图教程
Apr 16 Javascript
浅析Visual Studio Code断点调试Vue
Feb 27 Javascript
cnpm加速Angular项目创建的方法
Sep 07 Javascript
小程序绑定用户方案优化小结
May 15 Javascript
深入理解基于vue-cli的webpack打包优化实践及探索
Oct 14 Javascript
详解ES6数组方法find()、findIndex()的总结
May 12 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
攻克CakePHP系列三 表单数据增删改
2008/10/22 PHP
PHP 中执行排序与 MySQL 中排序
2009/04/21 PHP
ThinkPHP实现非标准名称数据表快速创建模型的方法
2014/11/29 PHP
PHP解析url并得到url参数方法总结
2018/10/11 PHP
实例介绍PHP删除数组中的重复元素
2019/03/03 PHP
从父页面读取和操作iframe中内容方法
2009/07/25 Javascript
为javascript添加String.Format方法
2020/08/11 Javascript
JQuery下关于$.Ready()的分析
2009/12/13 Javascript
为jQuery增加join方法的实现代码
2010/11/28 Javascript
将HTMLCollection/NodeList/伪数组转换成数组的实现方法
2011/06/20 Javascript
JS实现网页滚动条感应鼠标变色的方法
2015/02/26 Javascript
jQuery插件slides实现无缝轮播图特效
2015/04/17 Javascript
使用JQuery实现的分页插件分享
2015/11/05 Javascript
阿里巴巴技术文章分享 Javascript继承机制的实现
2016/01/14 Javascript
巧方法 JavaScript获取超链接的绝对URL地址
2016/06/14 Javascript
jQuery Easyui使用(二)之可折叠面板动态加载无效果的解决方法
2016/08/17 Javascript
jquery组件WebUploader文件上传用法详解
2020/10/23 Javascript
js 获取html5的data属性实现方法
2017/07/28 Javascript
基于webpack 实用配置方法总结
2017/09/28 Javascript
Vuex中的State使用介绍
2019/01/19 Javascript
仿vue-cli搭建属于自己的脚手架的方法步骤
2019/04/17 Javascript
微信小程序实现下拉刷新动画
2019/06/21 Javascript
Vue+abp微信扫码登录的实现代码示例
2020/01/06 Javascript
基于JS正则表达式实现模板数据动态渲染(实现思路详解)
2020/03/07 Javascript
Python中模块pymysql查询结果后如何获取字段列表
2017/06/05 Python
python GUI库图形界面开发之PyQt5窗口类QMainWindow详细使用方法
2020/02/26 Python
详解python第三方库的安装、PyInstaller库、random库
2021/03/03 Python
Gerry Weber德国官网:优质女性时装,德国最大的时装公司之一
2019/11/02 全球购物
Guess荷兰官网:美国服饰品牌
2020/01/22 全球购物
毕业生造价工程师求职信
2013/10/17 职场文书
军训考核自我鉴定
2014/02/13 职场文书
社会学专业求职信
2014/07/17 职场文书
考试作弊检讨书
2014/10/21 职场文书
交通事故协议书范文
2014/10/23 职场文书
个人原因辞职信模板
2015/05/13 职场文书
教你怎么用Python操作MySql数据库
2021/05/31 Python