node.js - 如何模拟来自 http.request 的响应(nodejs、jasmine、sinon)

标签 node.js http mocking jasmine sinon

我已经编写了一个小的 node 模块来发出 http 请求,但我在测试它时遇到了问题。
有问题的代码如下所示:

module.exports = (function () {
    var http = require("http"),
        Promise = require("promise");

    var send = function send(requestOptions, requestBody) {
        return new Promise(function (resolve, reject) {

            http.request(requestOptions, function (response) {
                var responseChunks = [];

                response.on('data', function (chunk) {
                    responseChunks.push(chunk);
                });

                response.on('end', function () {
                    resolve(Buffer.concat(responseChunks));
                });

                response.on('error', function (e) {
                    reject(e);
                });
            }).end(requestBody);
        });
    };

    return {
        send: send
    }

我正在尝试测试我的 send 方法,特别是 http.request 调用的回调函数。
认为我需要做的是从 http.request 模拟或 stub response 对象,这样我就可以测试回调函数。但我不知道该怎么做。

如果有任何相关性,我正在使用 node v4.1、jasmine v2.3 和 sinon v1.17

最佳答案

您可以尝试创建一个本地或“模拟”服务器来响应您的请求,而不是 stub 。这避免了必须 stub http.request。本地服务器的好处之一是,无论您是使用 http.request、XMLHttpRequest 还是类似的方法来获取在线资源,此方法都应该有效。

模拟服务器

你可以试试mock server .有了它,您可以创建一个假服务器来满足您的请求。

正在安装

npm install mockserver-grunt --save-dev
npm install mockserver-client --save-dev

Jasmine 代码

在您的规范(或测试)中,您可以使用以下内容(根据您的需要进行更改):

var mockServer = require("mockserver-grunt");
var mockServerClient = require("mockserver-client").mockServerClient;

beforeAll(function(done) {
  // start the server
  mockServer.start_mockserver({
    serverPort: 1080,
    verbose: true
  });

  // setup how to respond
  let response = {name:'value'};
  let statusCode = 203;
  mockServerClient("localhost", 1080).mockSimpleResponse('/samplePath', response, statusCode);

  setTimeout(function() {
    // give time for the mock server to setup
    done();
  }, 4000);
});

it("should be able to GET an online resource", function(done) {
   // perform tests, send requests to http://localhost:1080/samplePath
}

这将在端口 1080 上启动服务器。向 http://localhost:1080/samplePath 发出的任何请求将收到提供的响应。

以类似的方式,可以在测试结束时关闭服务器:

afterAll(function() {
  mockServer.stop_mockserver({
    serverPort: 1080,
    verbose: true
  });
});

其他说明

修复损坏的 jar 文件

当服务器首次启动时,它会尝试下载服务器所需的 jar 文件。这是一次性下载(据我所知)。如果没有提供足够的时间,它将无法完全下载,您最终会得到一个无效或损坏的 jar 文件。要更正此问题,您可以自己下载 jar 文件。该链接在运行中提供。对我来说,它位于 https://oss.sonatype.org/content/repositories/releases/org/mock-server/mockserver-netty/3.10.6/mockserver-netty-3.10.6-jar-with-dependencies.jar。 .您很可能希望导航到最新版本。


更新

Express JS 服务器

自从我最初发布后,我发现了 Express JS。 Express 启动服务器实例的速度比 Mock Server 快得多。您也不必担心 jar 文件。

正在安装

npm install express --save-dev

Jasmine 代码

var express = require('express');
var app = express();
var port = 3000;
var server;

beforeAll(function() {
  server = app.listen(port, function() {
    console.log("Listening on port " + port);
  });

  app.get('/samplePath', function (req, res) {
    res.send("my response");
  });

});

afterAll(function() {
  // shutdown
  server.close();
});

it("should be able to GET an online resource", function(done) {
   // perform tests, send requests to http://localhost:3000/samplePath
}

如果你想花哨一点,你可以返回你使用的路径。例如,如果您转到 http://localhost:3000/helloworld ,返回值将是 helloworld。您可以根据自己的需要进行调整。

app.get('/*', function (req, res) {
  res.send(req.params[0]);
});

如果你需要强制代码沿着错误路径走,你可以使用

res.status(404)        // HTTP status 404: NotFound
 .send('Not found');

来源:How to programmatically send a 404 response with Express/Node?


使用 HTTPS 配置 Express JS

Express JS 可以配置为使用 HTTPS。使用 openssl,可以使用以下方法创建自签名证书:

openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -days 365

来源:How to create a self-signed certificate with openssl?

使用以下内容更新 express js 代码以使用 HTTPS。

const secureOptions = {
   key: fs.readFileSync("./spec/ExpressServer/key.pem"),
   cert: fs.readFileSync("./spec/ExpressServer/cert.pem")
};

var secureServer = https.createServer(secureOptions, app);

注意:您可能必须配置应用程序的安全性以允许 HTTPS 的自签名证书。

关于node.js - 如何模拟来自 http.request 的响应(nodejs、jasmine、sinon),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33393779/

相关文章:

java - 如何正确地将格式化的日期时间传递到 HTTP 请求中?

node.js - NodeJS/Express/Mongoose 出现错误无法在发送后设置 header

javascript - 根据 JSON 的值和 JSON 数组的键合并一个 JSON 和 JSON 数组

javascript - 帖子正文中缺少必需参数 To

http - 协议(protocol)逆向工程/重现HTTP对话

python - 检查是否使用不同参数多次调用函数

node.js - 使用 GM() 和 NodeJS 制作马赛克图像

angular - 如何在 Angular 5 中从 http 重定向到 https?

node.js - 在 Node 中模拟 postgres 调用

java - 模拟网络服务