Chakram请求返回未定义的响应

时间:2018-03-19 13:06:58

标签: node.js http protractor chakram

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

我有一个负责访问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 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

我可以确认我正在点击的服务器正在运行,并且在使用网络浏览器时我可以得到正确的响应。

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

为什么Chakram根本没有收到回复?

2 个答案:

答案 0 :(得分:1)

根本原因

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遇到了我在本地开发环境中使用的自签名证书的问题。其他服务器托管在云中,并正确设置其证书。

解决方法

快速Google搜索通过设置:

返回了许多建议来修改驱动此行为的全局参数
process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";

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

值得庆幸的是,chakram.get使用request库,可以非常自定义请求。

chakram.get允许我通过:

  

params对象可选的其他请求选项,请参阅热门request library选项

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

  

agentOptions - 并传递其选项。注意:对于HTTPS,请参阅tls API doc for TLS/SSL options和上述文档。

最后,在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;
});

尽管使用自签名证书,这仍然可以使测试成功。

解决方案

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

答案 1 :(得分:-1)

这是因为它的异步和ur函数在没有完成chakram请求的情况下执行。 等待请求完成以获得响应。