淺析Node.js中使用依賴注入的相關問題及解決方法
最近,我轉(zhuǎn)向使用依賴注入來幫助理解分離代碼的簡單途徑,并有助測試。然而,Node.js中的模塊依賴Node提供的系統(tǒng)API,這很難判斷私有依賴被恰當?shù)氖褂?。一般的依賴注入很難在這種情況下使用,但現(xiàn)在不要放棄希望。
requireCauses 問題
Node.js很容易依照需求導入依賴。它運行的很好,并且比AMD模式加載器例如RequireJS要簡單。當我們模擬那些依賴的時候問題就來了。如果Node.js中模型的加載是受控的,我們怎么做才能控制讓偽對象在測試期間被使用到?我們可以使用Node的vm模式,通過vm我們可以再新的上下文中加載模型。運行在新的上下文中,我們可以控制需求反射出模型的方法。
解決方案
謝謝這篇文章, 現(xiàn)在可以給你提供一個相當不錯的解決方案. 代碼在下面:
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; };
你也可以在 這里 下載代碼片段 . 雖然在不是在文章發(fā)布最多的代碼, 他仍然可以使用一些解釋. 當我們測試時, 我們要加載這個模塊進入測試, 使用theloadModulefunction代替ofrequire加載模塊測試.
第一個參數(shù)filePath指定了我們要測試模型的查找位置。第二個參數(shù)mocks包含一個對象,對象的屬性名稱要和我們嘗試require的模型的名稱相匹配。那些屬性指定的值就是偽對象,用來代替一般被require的模型。
本質(zhì)上看就是用vm來加載和運行模型在另一個“上下文”中。換句話說,我們重建了全局變量(例如require和exports)以便我們能控制它們。需要注意的是我們編寫了一個可用的新require函數(shù)。所做一切就是檢查一下用執(zhí)行的名字是否有一個模擬的依賴,如果每日有,我就就把它委托給那個常用的require函數(shù)。
使用模塊加載器的例子
如果你還有點困惑,你可以看下面的代碼示例,看它在上下文中的使用,也許能幫你清楚一些。首先,我們創(chuàng)建一個簡單的模塊。
var fs = require('fs'); module.exports = { // Do something with `fs` } 想象一下這個很酷,對嗎?不管怎樣,現(xiàn)在我們測試那個模塊,但是我們要模擬fs來看看它是怎么在內(nèi)部使用的。 // 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行,我們?yōu)閒s創(chuàng)建了一個偽對象并使用我們新的loadModule函數(shù)將這個使用的對象聯(lián)系到上面的小模塊中(我的意思是真棒!請記住,這是真棒,對不對?)。
相關文章
Node.js學習之查詢字符串解析querystring詳解
這篇文章主要給大家介紹了關于Node.js查詢字符串解析querystring的相關資料,文中通過示例代碼介紹的非常詳細,對大家學習或者使用node.js具有一定的參考學習價值,需要的朋友們下面來一起看看吧。2017-09-09npm ERR! code ELIFECYCLE錯誤及解決方法
有時候在使用npm運行命令時,可能會遇到錯誤,本文主要介紹了npm ERR! code ELIFECYCLE錯誤及解決方法,具有一定的參考價值,感興趣的可以了解一下2024-05-05node.js中的fs.realpathSync方法使用說明
這篇文章主要介紹了node.js中的fs.realpathSync方法使用說明,本文介紹了fs.realpathSync的方法說明、語法、接收參數(shù)、使用實例和實現(xiàn)源碼,需要的朋友可以參考下2014-12-12Node.js發(fā)起HTTP請求的6種不同方法小結(jié)
本文主要介紹了Node.js發(fā)起HTTP請求的6種不同方法小結(jié),文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2022-03-03