【问题标题】:How to create a mock http.ServerRequest and http.ServerResponse?如何创建模拟 http.ServerRequest 和 http.ServerResponse?
【发布时间】:2013-12-20 03:20:22
【问题描述】:

我已经为http.Serverrequest event 编写了一个处理程序(即带有签名function (request, response) { ... } 的函数),我想对其进行测试。我想通过模拟 http.ServerRequesthttp.ServerResponse 对象来做到这一点。如何创建这些?

明显的方法似乎不起作用:

$ node
> var http = require('http');
> new http.ServerRequest();
TypeError: undefined is not a function
    at repl:1:9
...

我是否需要通过“真实”的 HTTP 服务器和客户端对此进行测试?

【问题讨论】:

  • 如果你想测试它,那么真正这样做有什么坏处。
  • @user568109 好吧,代码本身没有网络依赖,所以测试似乎没有必要(而且更慢)需要网络。

标签: node.js testing


【解决方案1】:

至少有两个项目允许模拟 http.ServerRequesthttp.ServerResponsehttps://github.com/howardabrams/node-mocks-httphttps://github.com/vojtajina/node-mocks

由于某种原因,通过真实的 HTTP 请求进行测试似乎更常见; https://github.com/flatiron/nock 似乎是这里使用的工具。

另见node.js: Mock http request and response

【讨论】:

  • node-mocks-http 似乎相当有限,因为它不允许您将请求正文作为流写入
【解决方案2】:

是的,您可以使用http.request 来完成。它允许您从服务器发出请求,因此您可以使用代码对其进行测试。如果你想发送简单的 GET 请求,你可以使用 http.get ,这更容易。否则,您将不得不自己构建您的请求。来自文档的示例:

var options = {
  host: 'www.google.com',
  port: 80,
  path: '/upload',
  method: 'POST'
};

var req = http.request(options, function(res) {
  res.setEncoding('utf8');
  console.log('STATUS: ' + res.statusCode);
  res.on('data', function (chunk) {
    console.log('BODY: ' + chunk);
  });
});

req.on('error', function(e) {
  console.log('problem with request: ' + e.message);
});

req.write('data\n');
req.end();

如果您使用的是request,您也可以这样做。

var request = require('request');
request.post( url, json_obj_to_pass,
    function (error, response, body) {
        if (!error && response.statusCode == 200)
            console.log(body)
    }
);

【讨论】:

    【解决方案3】:

    我为http.ServerResponse 创建了一个简单而基本的模拟,要点是here,对于http.ServerRequest,我使用rewire

    首先加载依赖:

    var require = require('rewire'),
        events = require('events'),
        util = require('util');
    

    这是http.ServerResponse 模拟。它基本上创建一个与http.ServerResponse方法相同的对象,然后使用util模块继承events模块。

    /**
     * Mock https.serverResponse
     * @type {Object}
     */
    var mockResponse;
    Eventer = function(){
        events.EventEmitter.call(this);
    
        this.data = '';
    
        this.onData = function(){
            this.emit('data', this.data);
        }
    
        this.setEncoding = function(){
    
        }
    
        this.onEnd = function(){
            this.emit('end', this.data);
        }
    
        this.run = function(){
            this.onData();
            this.onEnd();
        }
    };
    util.inherits(Eventer, events.EventEmitter);
    

    然后我使用这个带有 rewire 的模拟来覆盖 http 模块的 get()、request() 或任何其他库。

    /**
     * Mocks literal object for rewire mocking.
     * @see https://github.com/jhnns/rewire
     * @type {Object}
     */
    var mocks = {
        "https" : {
            "get" : function(url, fn){
                fn(mockResponse.data);
                mockResponse.run();
            }
        }
    };
    
    //instead of: var myModule = require('myModule');
    //do:
    var myModule = rewire('myModule');
    myModule.__set__(mocks);
    

    现在你模块中的http 库被模拟了

    【讨论】:

      猜你喜欢
      • 2015-12-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-10-04
      • 2015-06-09
      • 1970-01-01
      • 1970-01-01
      • 2015-06-25
      相关资源
      最近更新 更多