如何用rewire模拟请求模块?

我有一个自定义模块tokens.js与通过npm请求模块发出请求的函数。 它看起来像这样:

'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); }); }); 

我想编写unit testing来覆盖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?

另一种select是重构代码,以便轻松configuration其依赖关系。

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

testing代码

 // 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); 

有很多策略让你的类可configuration,并允许有机会注入假物体进行testing。 我相信努力编写可testing性的代码应该可以消除在项目中添加更多第三方依赖的需求。

其实我find了一个模拟请求模块的方法。 我只是让requestMock一个函数。 另外我发现在请求模块中有一行,这使得它成为可能: module.exports = request