Chakram 请求返回的未定义响应

Undefined response returned by Chakram requests

我在使用 Protractor 编写的自动化测试中遇到了一个奇怪的问题。我们需要通过 HTTP 测试 return JSON 的一堆 API 端点,而不是实际的网站,因此我的团队决定使用 Chakram 而不是依赖量角器。

我有一个页面对象负责访问 API:

const qs = require('querystring')
const chakram = require('chakram');

function MyApi() {

  const domain = // read from a configuration file

  this.readImportantBusinessData = (queryParams) => {
    const serviceUrl = `${domain}/services/seriousBusiness.json`;
    const queryString = qs.stringify(queryParams);
    const fullUrl = `${serviceUrl}?${queryString}`;
    return chakram.get(fullUrl).then((response) => {
      return response;
    });
  };
};

module.exports = new MyApi();

然后,在我的一个规范中,我调用 readImportantBusinessData 函数来检查它是否 return 是预期的数据。

return MyApi.readImportantBusinessData(validParameters).then((response) => {
        chakramExpect(response).to.have.status(HTTP_200_OK);
        chakramExpect(response).to.have.json({
            "foo" : "bar"
        });
      });

根据我 运行 此代码所在的环境,测试通过或失败并显示一条错误消息,这基本上意味着未收到任何响应。

Failed: Cannot read property 'statusCode' of undefined

我可以确认我正在访问的服务器是 运行ning 并且我可以在使用网络浏览器时得到正确的响应。

当我使用 AWS 中托管的共享服务器时,我的测试中的请求成功,而当我使用 VirtualBox 中的本地服务器 运行ning 时失败。

为什么 Chakram 根本收不到回复?

根本原因

expect 的调用刚刚显示 undefined 但我设法记录了整个响应对象,如 chakram.get

返回的
{ error: { Error: self signed certificate
  at TLSSocket.<anonymous> (_tls_wrap.js:1103:38)
  at emitNone (events.js:106:13)
  at TLSSocket.emit (events.js:208:7)
  at TLSSocket.finishInit (_tls_wrap.js:637:8)
  at TLSWrap.ssl.onhandshakedone (_tls_wrap.js:467:38) code: 'DEPTH_ZERO_SELF_SIGNED_CERT' },
  response: undefined,
  body: undefined,
  jar:
       RequestJar {
         jar: CookieJar { enableLooseMode: true, store: { idx: {} } } 
       },
  url: 'https://www.example.com/myService.json?foo=bar',
  responseTime: 29.524212 
}

这意味着 Chakram 在我用于本地开发环境的 self-signed 证书方面存在问题。其他服务器托管在云中并正确设置了它们的证书。

解决方法

快速 Google 搜索返回了很多建议来修改通过设置驱动此行为的全局参数:

process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";

但是,这会影响整个节点进程,而不仅仅是我的测试。这些只是我在本地 运行 进行的测试,与实际用户数据无关。尽管如此,如果我要使这些调用的安全性更加宽松,我需要它来尽可能地限制此类更改的范围。

谢天谢地,chakram.get uses the request 库可以大量自定义请求。

chakram.get 让我通过:

params Object optional additional request options, see the popular request library for options

这些options,反过来允许我指定:

agentOptions - and pass its options. Note: for HTTPS see tls API doc for TLS/SSL options and the documentation above.

最后,在 agentOptions 中,可以传递一个 rejectUnauthorized 值,允许忽略证书错误 对正在发出的单个请求

因此,在我的页面对象中,我可以使用:

return chakram.get(fullUrl, {
  agentOptions : {
    //Hack to allow requests to the local env with a self-signed cert
    rejectUnauthorized : false
  }
}).then((response) => {
  return response;
});

尽管使用 self-signed 证书,这仍允许测试成功。

解决方案

解决方案是为每个环境和域提供有效的证书,在这种情况下问题首先就不存在了。

这是因为它的异步和你的功能在甚至没有完成你的脉轮请求的情况下就被执行了。 等待请求完成以获得响应。