浅析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 相关文章推荐
jquery和ajax的关系详细介绍
Nov 29 Javascript
常用的JavaScript WEB操作方法分享
Feb 28 Javascript
javascript常用的方法整理
Aug 20 Javascript
jquery限定文本框只能输入数字(整数和小数)
Jan 08 Javascript
js实现对ajax请求面向对象的封装
Jan 08 Javascript
JS点击某个图标或按钮弹出文件选择框的实现代码
Sep 27 Javascript
jQuery UI仿淘宝搜索下拉列表功能
Jan 10 Javascript
vue数据双向绑定原理解析(get & set)
Mar 08 Javascript
H5图片压缩与上传实例
Apr 21 Javascript
简单实现js进度条加载效果
Mar 25 Javascript
详解vue中async-await的使用误区
Dec 05 Javascript
如何用vue实现网页截图你知道吗
Nov 17 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
用php获取本周,上周,本月,上月,本季度日期的代码
2009/08/05 PHP
php array_search() 函数使用
2010/04/13 PHP
php中XMLHttpRequest(Ajax)不能设置自定义的Referer的解决方法
2011/11/26 PHP
PHP 输出URL的快捷方式示例代码
2013/09/22 PHP
JQuery下拉框应用示例介绍
2014/04/23 Javascript
基于JavaScript实现鼠标悬浮弹出跟随鼠标移动的带箭头的信息层
2016/01/18 Javascript
js实现页面跳转的五种方法推荐
2016/03/10 Javascript
轻松掌握JavaScript装饰者模式
2016/08/27 Javascript
浅谈JS之iframe中的窗口
2016/09/13 Javascript
详解AngularJS用Interceptors来统一处理HTTP请求和响应
2017/06/08 Javascript
Vue单文件组件的如何使用方式介绍
2017/07/28 Javascript
jQuery实现菜单栏导航效果
2017/08/15 jQuery
vue.js组件vue-waterfall-easy实现瀑布流效果
2017/08/22 Javascript
基于js 字符串indexof与search方法的区别(详解)
2017/12/04 Javascript
最适应的vue.js的form提交涉及多种插件【推荐】
2018/08/27 Javascript
JS学习笔记之数组去重实现方法小结
2019/05/29 Javascript
如何利用JavaScript编写更好的条件语句详解
2020/08/10 Javascript
原生JavaScript实现贪吃蛇游戏
2020/11/04 Javascript
python实现在目录中查找指定文件的方法
2014/11/11 Python
Python  unittest单元测试框架的使用
2018/09/08 Python
详解Python中pandas的安装操作说明(傻瓜版)
2019/04/08 Python
python实现控制台输出彩色字体
2020/04/05 Python
Python rabbitMQ如何实现生产消费者模式
2020/08/24 Python
使用CSS实现阅读进度条
2017/02/27 HTML / CSS
html5小技巧之通过document.head获取head元素
2014/06/04 HTML / CSS
html5定位获取当前位置并在百度地图上显示
2014/08/22 HTML / CSS
使用HTML5加载音频和视频的实现代码
2020/11/30 HTML / CSS
澳大利亚先进的皮肤和激光诊所购物网站:Soho Skincare
2018/10/15 全球购物
中专毕业自我鉴定
2013/10/16 职场文书
编辑硕士自荐信范文
2013/11/27 职场文书
如何写一份好的英文求职信
2014/03/19 职场文书
2016幼儿园教师年度考核评语
2015/12/01 职场文书
浅谈python中的多态
2021/06/15 Python
JavaScript 数组去重详解
2021/09/15 Javascript
游戏《东方异文石:爱亚利亚黎明》正式版发布
2022/04/03 其他游戏
python数字图像处理实现图像的形变与缩放
2022/06/28 Python