2016-07-23 77 views
2

我有一個自定義模塊tokens.js具有通過npm請求模塊發出請求的功能。它看起來像這樣:如何使用rewire模擬請求模塊?

'use strict'; 

let request = require('request'); 

module.exports.getToken = function(code, cb) { 
    let url = 'some_url'; 

    request(url, function (err, response, body) { 
    if (err) { 
     return cb(err); 
    } else if (response.statusCode !== 200) { 
     return cb('err'); 
    } 

    parseGetResponse(body, function (err, token) { 
     if (err) { 
     return cb(err); 
     } 

     return cb(null, token); 
    }); 
}); 

我想寫單元測試覆蓋爲gettoken()函數,但我有一些麻煩與嘲諷請求模塊。

我嘗試這樣做:

let mocha = require('mocha'); 
let rewire = require('rewire'); 
let should = require('should'); 

let requestMock = { 
    request: function (url, cb) { 
     // return cb(); etc 
    } 
} 

let tokens = rewire('services/tokens.js'); 
tokens.__set__('request', requestMock); 

但這種方法是行不通的:

TypeError: request is not a function 
    at Object.module.exports.getToken (services/tokens.js) 

實際上,它引出了另一個問題: 如何請求模塊可以不工作直接調用導出函數(request.request(url,cb))?我應該如何使用rewire?

回答

1

另一種選擇是重組的代碼,以便其依賴性易於配置。

function TokenGetter(request) { 
    this.request = request || require('request'); 
    this.getToken = function(code, cb) { ... 
} 
module.exports.TokenGetter = TokenGetter; 

// production code 
var tokenGetter = new TokenGetter(); 

測試代碼

// test code can configure a mock request for your test, no 
// 3rd party libraries 
// configure mockObject with assertions/return values 
var mockRequest = function(url, cb) { .... ; 

var testTokenGetter = new TokenGetter(mockRequest); 

要做出你的類配置,並允許有機會注入虛假對象進行測試許多策略。我相信努力編寫可測試性代碼應該可以消除爲項目添加更多第三方依賴項的需求。

+0

我甚至沒有想到node.js中的DI方法。我會嘗試這種方式,謝謝。 – t1maccapp

+0

你可以檢查https://stackoverflow.com/questions/46952843/mock-module-which-does-not-exist/46954753我想嘲笑'流星/流星'的位置或一般'從流星導入流星' /流星'這是不存在的,因爲我開始我的測試'npm直接運行摩卡測試'而不是'流星測試'。不幸的是,很多代碼依賴於'流星'環境。 – Gobliins

0

其實我找到了一種方法來模擬請求模塊。我只是讓requestMock成爲一個函數。此外,我發現,在請求模塊有一條線,使得能夠: module.exports =請求