前一陣子在寫單元測試(unit test)時,遇到一些問題,經過同事的提點,看到了 rewire 這個 github repo
當在寫測試時,我們可能會分許多檔案去管理我們的模組,然而模組內可能有一些 private 的方法,這時候如果想測試模組內的 private 方法該如何測試呢?
以往可能的作法: 設定環境變數(例如:test: true
),在測試環境時才 export prviate 方法。
但 rewire 這個 npm package 提供一層更方便測試 private 的方法。
接下來看看實際用法吧~
比如我們有 test.js
[javascript]
function add(a, b) {
return a+b;
}
function addExpression(a, b) { return a + ’ + ’ + b + ’ = ’ + add(a,b); }
module.exports = { add: addExpression };
[/javascript]
index.js 則會 require('test.js');
這個模組
[javascript] var test = require(‘./test.js’); console.log(test.add(1,2)); [/javascript]
當我們要寫 unit test 時會發現 test.js 的 add() 因為沒有 export 所以無法被測試,或是當在測試 test 模組時,也沒辦法把 add 做 stub(因為 js 在 function 會是 call by value)
這時候我們可以使用 rewire 去取代 require,如下面的程式碼
[javascript]
var rewire = require(‘rewire’);
var test = rewire(‘test.js’);
console.log(test.add(1,2)); // 1 + 2 = 3
// 替換 test.add 方法(stub)
var revert = test.__set__(‘add’, function(){ return 100; });
console.log(test.add(1,2)); // 1 + 2 = 100
// 還原 test.add 方法
revert();
// 取得 add 方法
console.log(test.__get__(‘add’));
[/javascript]
上面這些例子(__set__
、__get__
及 revert
)就是 rewire 的基本應用了,其實仔細去看一下 rewire github 的原始碼,會發現他的做法,其實就是在 rewire 檔案進來之後,多包一層 function ,並且增加 __get__
及 __set__
…這些方法,將原來模組內 global 的變數透過這些方法去做存取。
某種程度也就是將 private 的函式 export 出來,不過正常僅會在 test 的環境及程式碼中使用 rewire,因此相對不會汙染到原來的原始碼。
參考資料: