首頁 > web前端 > js教程 > 主體

淺析Node.js中使用依賴注入的相關問題及解決方法_node.js

WBOY
發布: 2016-05-16 15:53:17
原創
1215 人瀏覽過

最近,我轉向使用依賴注入來幫助理解分離程式碼的簡單途徑,並有助測試。然而,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函數將這個使用的對象聯繫到上面的小模組中(我的意思是真棒!請記住,這是真棒,對不對?

相關標籤:
來源:php.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板
關於我們 免責聲明 Sitemap
PHP中文網:公益線上PHP培訓,幫助PHP學習者快速成長!