如何使用 Chai 和 Sinon 在 NodeJS 项目中对 REST API 进行测试

阅读时长 7 分钟读完

NodeJS 作为一种流行的服务器端运行环境,其广泛的应用与快速增长的社区开发了许多有用的工具和库。测试是项目开发过程中必不可少的一步,它可以帮助我们发现和修复潜在的错误、提高代码的质量和可靠性。在这篇文章中,我们将介绍如何使用 Chai 和 Sinon 对 NodeJS 项目中的 REST API 进行测试。

Chai 和 Sinon 简介

Chai 是一种 JavaScript 测试框架,它提供了许多断言函数,可以用于编写可读性高的测试代码。Chai 可以与不同的测试框架结合使用,如 Mocha、Jasmine、Karma 等。

而 Sinon 则是一个用于测试 JavaScript 代码的工具库,它可以帮助我们创建 spies、stubs 和 mocks 等测试对象,并提供了丰富的接口帮助我们测试异步代码。Sinon 同样可以与不同的测试框架结合使用。

安装和设置

首先,我们需要安装 Chai 和 Sinon,使用 npm 可以轻松完成安装:

安装完成之后,在测试文件中,我们需要引入所需的库:

编写测试用例

考虑我们有一个简单的 REST API,它实现了一个 POST 请求,用于创建一条数据。该 API 要求请求体包含一个名为 name 的属性,如果请求体中没有该属性,则返回 400 Bad Request 错误。为了编写测试用例,我们需要构建一个测试文件。

我们可以用 Mocha 作为测试框架,将所有测试用例放在 describe() 函数中,it() 函数用于具体描述每个测试用例:

-- -------------------- ---- -------
----- ------- - ---------------------
----- --- - ------------------

-------------- ----------- -- -- -
  ---------- ------ --- -- --- ----- --------- ------ -- -
    ------------
      ------------------
      ------- ----- ------- --
      ---------- ---- -- -
        -------------------------------------
        -------
      ---
  ---

  ---------- ------ --- --- ------- --- ------- ---- ---------- ------ -- -
    ------------
      ------------------
      ---------- ---- -- -
        -------------------------------------
        -------
      ---
  ---
---

在第一个测试用例中,我们发送一个包含 name 属性的 POST 请求,期望返回 200 OK;在第二个测试用例中,我们发送一个不包含 name 属性的 POST 请求,期望返回 400 Bad Request。

在执行这些测试用例之前,我们需要为名为 app 的 Express 应用程序编写代码。这部分代码将根据请求处理所有 HTTP 动词和路径,但是现在让我们专注于测试代码。

在测试代码中,我们使用了 supertest 模块来模拟 HTTP 请求并检查响应,该模块可以与所有 NodeJS HTTP 框架一起使用,如 Express、Koa、Hapi 等。

现在,我们运行测试代码,你会发现两个测试用例都通过了!但是,在实际开发中,我们会遇到更复杂的测试情况,例如:如何测试我们的 API 调用了另一个 API、如何测试异步代码等等。

使用 Sinon 生成 Mock 和 Stub

Sinon 的 stub 和 mock 可以帮助我们创建模拟函数和对象,以便测试我们的代码。我们来看一些示例。

在这个例子中,我们有一个处理 GET 请求的代码,它发送了一个请求到另一个 API 并返回响应的 body 部分。在测试时,我们不想调用实际的 API,因此我们可以使用 Sinon stub 来模拟这个 API:

-- -------------------- ---- -------
----- ----- - -----------------
----- ------- - ---------------------------
----- --- - ---------------------

------------- ----------- -- -- -
  ---------- ------ --------- ----- -- -- -
    ----- ------------ - - ----- -- --- -- ----- ------- -- --
    ----- ----------- - ------------------- ------------------------------

    ----- -------- - ----- ------------------------------

    ------------------------------------------
    --------------------------------------------------
    ------------------------------------------

    ----------------------
  ---
---

在此示例中,我们使用了 sinon.stub() 创建了一个模拟函数,函数的返回值是预先设置的 responseBody。在用 request(app).get() 发送实际请求之前,我们拦截了 request.get() 的调用,返回了模拟函数的值。我们使用 .resolves() 以 Promise 形式解析函数的返回值。

在测试中,我们可以断言响应的状态码、body 和模拟函数是否被调用(这里使用了 sinon 的 spy 方法 .calledOnce)。最后,我们需要在 stub 使用完后,调用 restore() 方法,将其还原为 original (该恢复方法在 afterEach() 中同样适用)。

使用 Sinon 来测试异步代码

在测试异步代码时,我们经常会遇到有界面或服务端元素根据一定条件进行渲染或响应,这时候我们可以使用 Sinon.fakeTimers 或 Sinon.useFakeTimers() 方法。

在这个例子中,我们有个处理 PUT 请求的代码,它发送请求到另一个 API,并在 5 秒后返回“成功”。在测试时,我们想确保返回消息在请求之后的准确时间到达。

-- -------------------- ---- -------
----- ----- - -----------------
----- ------- - ----------------------
----- --- - ------------------

------------- ----------- -- -- -
  ---------- ------ ------- ------- ----- - --------- ------ -- -
    ----- ----- - ----------------------
    ----- ------------ - ----------

    ------------------- ------------------

    ------------
      -----------------
      ---------- ----- ---- -- -
        ----------------------------------------
        ------------------------------------------

        ----------------------
        ----------------
        -------
      ---

    -----------------
  ---
---

在这个例子中,我们首先使用 Sinon.useFakeTimers() 方法创建时间模拟器。我们也使用了 defer() 方法来延迟使用的解析,最后使用 clock.tick() 来模拟 5 秒过去的时间。

在发送的 PUT 请求期间,我们使用了 Sinon 的 .resolves() 方法,确定了请求函数返回的业务上的成功。在结束期间我们使用 .restore() 操作将所有 stub 和 clock 恢复。

总结

在这篇文章中,我们介绍了如何使用 Chai 和 Sinon 在 NodeJS 项目中对 REST API 进行测试。我们学习了如何使用 supertest 创建模拟 HTTP 请求,并如何使用 Sinon 来创建模拟函数和对象以及测试异步代码。

测试是软件开发过程中非常重要的一步,可以帮助我们提高应用程序的质量和可靠性。同时,测试也有很大的指导意义,在开发过程中帮助我们发现一些潜在的 bug 和设计问题。希望这篇文章能够帮助你更好地理解和使用 Chai 和 Sinon,以及改善你的代码测试策略。

来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/64f21c61f6b2d6eab3bde053

纠错
反馈