简体   繁体   English

如何使用重新连接模拟请求模块?

[英]How to mock request module with rewire?

I have a custom module tokens.js with a function which makes requests via npm request module . 我有一个自定义模块tokens.js ,其功能通过npm请求模块发出请求。 It looks like this: 它看起来像这样:

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

I'd like to write unit tests to cover getToken() function, but I have some troubles with mocking request module. 我想编写单元测试来覆盖getToken()函数,但是我遇到了一些模拟请求模块的麻烦。

I tried this: 我试过这个:

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

But this approach doesn't work: 但这种方法不起作用:

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

Actually, it leads to another question: How request module may works without directly calling exported function (request.request(url, cb)) ? 实际上,它引出了另一个问题: 请求模块如何在不直接调用导出函数(request.request(url,cb))的情况下工作 And how should I use rewire with this? 我该如何使用重新连线呢?

Another option is to restructure the code so that its dependencies are easily configured. 另一种选择是重构代码,以便轻松配置其依赖关系。

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 测试代码

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

There are many strategies for making your classes configurable, and allowing the opportunity to inject fake objects for testing. 有许多策略可以使您的类可配置,并允许有机会注入假对象进行测试。 I believe striving to write code for testability should eliminate the need to add even more 3rd party dependencies to your project. 我相信努力编写可测试性代码应该可以消除为项目添加更多第三方依赖项的需要。

Actually, I found a way to mock request module. 实际上,我找到了一种模拟请求模块的方法。 I just make requestMock a function. 我只是让requestMock成为一个函数。 Also I found out that in request module there is a line, that makes it possible: module.exports = request 另外我发现在请求模块中有一行,这使得它成为可能: module.exports = request

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM