如何使用 Jest 测试 NestJS 应用程序

阅读时长 22 分钟读完

在前端开发领域,测试是必不可少的一个环节。而在 Node.js 应用程序中,常用的测试框架之一就是 Jest。而在 NestJS 框架中,如何使用 Jest 进行测试呢?本文将会详细介绍 Jest 的基本用法、NestJS 应用程序的测试方法和相关的示例代码。

前置技能

在学习本文之前,需要先掌握下列技能:

  • 基本的 TypeScript 知识
  • NestJS 框架入门知识,包括但不限于模块、控制器、服务、拦截器、管道和过滤器等
  • 基本的单元测试知识,包括但不限于测试框架、测试套件、测试用例、断言、mock、spy 和运行测试等

Jest 的基本用法

Jest 是 Facebook 开源的一个 JavaScript 测试框架,它可能是目前 Node.js 社区中最受欢迎的测试框架之一。它提供了优雅的语法、智能的默认配置和强大的插件系统,支持测试各种类型的 JavaScript 应用程序。

在使用 Jest 之前,我们需要先安装 Jest 和相关的依赖项:

安装完成后,我们需要对 Jest 进行一些基本的配置。在项目根目录下创建 jest.config.js 文件,添加以下内容:

这里的 preset 选项告诉 Jest 在 TypeScript 项目中进行测试,testEnvironment 选项告诉 Jest 在 Node.js 环境中进行测试。

完成这些基本配置之后,我们可以开始编写 Jest 测试代码了。在项目中创建一个名为 tests 的目录,用于存放测试代码。在 tests 目录中创建一个 example.test.ts 文件,添加以下测试代码:

这里的 describe 用于描述一个测试套件,it 用于描述一个测试用例,expect 用于断言测试结果。

运行测试命令:

这时候,我们应该能看到类似下面的输出:

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

---- ------- - ------- - -----
------       - ------- - -----
----------   - -----
-----        ----- -- --------- - -
--- --- ---- ------ -------- ---------
展开代码

这意味着我们的第一个 Jest 测试用例已经成功运行。

NestJS 中的测试

在 NestJS 中,使用 Jest 进行测试分为两部分。首先,我们需要准备好测试环境;然后,我们可以依照之前介绍的方法编写测试代码。

准备测试环境

在 NestJS 中准备测试环境需要以下步骤:

  1. 安装 @nestjs/testing 包:

  2. 创建 app.module.testing.ts 文件:

    -- -------------------- ---- -------
    ------ - -------------- - ---- ----------------------------
    ------ - ----- ------------- - ---- ------------------
    ------ - --------- - ---- --------------------
    
    ------ ----- --------------- -------------- - -
      -------- ------------
    --
    
    ------ ----- -------- --------------------
      --------- -------------- - ---
    -- ---------------------- -
      ----- --------- - ----- --------------------------
        ------------------
        ------------
      -------------
    
      ------ ----------
    -
    展开代码

    这里定义了一个 moduleMetadata 变量用于导入我们的应用主模块,另外定义了一个 createTestingModule 函数用于根据传递的元数据创建一个测试模块。

  3. 在测试用例中导入相关的包:

现在,我们已经可以准备好测试环境了。

编写测试代码

在编写测试代码的时候,我们需要分别对 NestJS 中的控制器、服务、拦截器、管道和过滤器等模块进行测试。

控制器测试

以 UserController 为例,假设我们有一个 UserController,代码如下:

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

--------------------
------ ----- -------------- -
  ------
  ---------- ------ -
    ------ ----- ------ ------- --- -------
  -
-
展开代码

控制器测试代码如下:

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

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

  ------------- -------- -- -- -
    ---------- ------ ----- ------ ------- --- -------- ----- -- -- -
      ----- ---------- - ----------------------------------------
      ----- ------ - ----- ---------------------
      ------------------------- ------ ------- --- --------
    ---
  ---
---
展开代码

这里的 app.get<UserController>(UserController) 返回了 UserController 实例,我们可以通过实例调用对应的方法并测试其返回值。

服务测试

以 UserService 为例,假设我们有一个 UserService,代码如下:

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

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

  ---------- -------- -
    ------ -----------
  -
-
展开代码

服务测试代码如下:

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

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

  ------------------- -- -- -
    ---------- ------ --- ------- ----- -- -- -
      ----- ------- - ----------------------------------
      ----- ------ - ------------------
      ----------------------------- ----- ----- -------
    ---
  ---
---
展开代码

这里的 app.get<UserService>(UserService) 返回了 UserService 实例,我们可以通过实例调用对应的方法并测试其返回值。

拦截器测试

以 LoggingInterceptor 为例,假设我们有一个 LoggingInterceptor,代码如下:

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

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

    ------ ----
      ---------
      ------------ -- --------------------- ------------ - -----------
  -
-
展开代码

拦截器测试代码如下:

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

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

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

    ----- ---------- - ------------------- -------
    ----------------------------- -- ----------------- ---- -- -------------
    --------------------------------------------
    -------------------------
  ---
---
展开代码

这里使用了 Jest 的 jest.fn()jest.spyOn() 方法分别对 switchToHttp()getRequest()handle()console.log() 方法进行 mock 和 spy,最终测试运行结果是否与预期一致。

管道测试

以 ValidationPipe 为例,假设我们有一个 ValidationPipe,代码如下:

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

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

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

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

  ------- ------ -------------------- ---------- ------- -
    ----- ------ ---------- - -------- -------- ------- ------ --------
    ------ --------------------------
  -
-
展开代码

管道测试代码如下:

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

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

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

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

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

    ----- ----------------------------- ---------------------------------
  ---
---
展开代码

这里使用了 Jest 的 jest.fn() 方法对 metatype 进行 mock,分别模拟了传入的参数中有错误和传入的参数中没有错误两种情况,并验证测试结果是否符合预期。

过滤器测试

以 HttpExceptionFilter 为例,假设我们有一个 HttpExceptionFilter,代码如下:

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

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

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

    ------------------------------
      ----------- -------
      --------
    ---
  -
-
展开代码

过滤器测试代码如下:

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

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

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

    ----------------------- ---- -- ---------------
    ---------------------------------------------------
  ---
---
展开代码

这里使用了 Jest 的 jest.fn() 方法对 switchToHttp()getResponse()status()json() 方法进行 mock,并验证测试结果是否符合预期。

示例代码

最后,我们将所有的测试代码整合在一起,作为此文的最终示例:

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    ----------------------- ---- -- ---------------
    ---------------------------------------------------
  ---
---
展开代码

通过上述示例,我们学习了 Jest 框架的基本用法及在 NestJS 应用程序中的测试方法。这些测试方法可以帮助我们在编写应用程序时进行快速测试,提高代码质量和稳定性。

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

纠错
反馈

纠错反馈