【问题标题】:Node.js - How to test HTTPS requests with promiseNode.js - 如何使用 Promise 测试 HTTPS 请求
【发布时间】:2019-01-02 15:42:14
【问题描述】:

我开始为我的 nodeJs 应用程序编写单元测试,以便了解这个概念。 在为简单函数(使用 Mocha 和 Chai)编写了一些基本测试之后,我想继续进行一些更复杂的测试。

我编写了一段简单的代码,可以使用节点的 HTTPS 模块发出请求。该代码如下所示:

const https = require('https')
 module.exports.doRequest = function (params, postData) {
  return new Promise((resolve, reject) => {
    const req = https.request(params, (res) => {
      let body = []
      res.on('data', (chunk) => {
        body.push(chunk)
      })
      res.on('end', () => {
        try {
          body = JSON.parse(Buffer.concat(body).toString())
        } catch (e) {
          reject(e)
        }
        resolve(body)
      })
    })
    req.on('error', (err) => {
      reject(err)
    })
    if (postData) {
      req.write(JSON.stringify(postData))
    }
    req.end()
  })
}

现在我想用以下参数调用这个方法:

const PARAMS = {
    host: 'jsonplaceholder.typicode.com',
    port: 433,
    method: 'GET',
    path: `/todos/1`,
    headers: {
      Authorization: 'Bearer 123'
    }
}

然后像这样发出请求:

getTodos = (PARAMS) => {
  return doRequest(PARAMS).then((result) => {
    if (result.errors) { throw result }
    return {
      'statusCode': 200,
      'body': JSON.stringify({ message: result.title }),
    }
  }).catch((error) => ({
      'statusCode': error.statusCode,
      'body': JSON.stringify({ message: error.message }),
    }
  ))
}

现在我的问题是如何正确测试这段代码。我已经研究过如何使用 Nock.js 库来解决这个问题,但我对从哪里开始没有很好的理解。 如果有人能指出我如何开始为这段代码编写一些测试的正确方向,我将不胜感激。

【问题讨论】:

    标签: javascript node.js unit-testing testing mocking


    【解决方案1】:

    一般来说,您会希望对 HTTP 处理进行黑盒化处理,以便您的应用程序中需要关注 HTTP 细节的模块越少越好。

    在源文件夹中,您将拥有一个模块(例如 commonhttp.js)。您希望它导出您的 HTTP 函数,并且应用程序中的其他模块像这样使用它们:

    const commonhttp = require('./commonhttp');
    commonhttp.doRequest( ... ).then( ... );
    

    其他模块,如todos.js,以及各种其他模块,将使用该模块导出自己的功能,例如:

    const commonhttp = require('./commonhttp');
    
    const todos = {
        getTodos( ... ) {
            return commonhttp.doRequest( ... );
        },
    
        createTodo( ... ) {
            return commonhttp.doRequest( ... );
        },
    
        // etc.
    };
    
    module.exports = todos;
    

    对于您的单元测试,当您测试todos.js 模块时,您希望模拟对commonhttp 模块的任何调用;您可以为此使用简单的 mocha + Sinon,并监视 doRequest 方法。基本上,您要测试的只是“当我调用 getTodos 时,我希望它使用这些参数调用 doRequest”。对于应用程序中使用 doRequest 的所有模块,您都应遵循此模式。

    当然,您还想测试commonhttp 模块——那个规范是 Nock 可能派上用场的地方。这不是绝对必要的,你也可以“block-box”http模块,但是你必须设置很多复杂的间谍来模仿http的行为;相反,编写一个规范(使用 Nock)说“好的,我用这些参数调用 doRequest,应该进行这个 HTTP 调用”确实有意义。

    【讨论】:

    • 感谢您的解释。现在我发现它更容易让我的思想围绕它:)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-08-12
    • 2021-07-24
    • 1970-01-01
    • 1970-01-01
    • 2012-07-10
    • 1970-01-01
    • 2011-12-26
    相关资源
    最近更新 更多