Enzyme 中 Mock 的坑和 trap,如何规避坑和解决 trap?

阅读时长 7 分钟读完

Enzyme 中 Mock 的坑和 trap,如何规避坑和解决 trap?

Enzyme 是 React 组件测试工具,Mock 是其核心功能之一。使用 Mock 可以模拟组件内部的函数或者 props,方便测试组件在不同状态下的行为和渲染结果。但是在使用 Mock 的过程中,我们也会遇到一些坑和 trap,本文将详细介绍这些问题,并提供解决方案和指导意义。

一、Mock 的坑

  1. Mock 不会改变原有函数的作用域

在使用 Mock 时,我们可能会遇到这样的问题:Mock 了一个函数,但是在组件内部调用这个函数时,它并没有被 Mock 控制,而是执行了原有的函数。这是因为 Mock 会创建一个新的函数,但是它并不会改变原有函数的作用域。

例如,我们有一个组件内部调用了一个全局函数:

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

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

我们想要在测试时 Mock 这个函数,可以这样写:

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

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

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

但是运行测试后,我们会发现测试失败了,输出的结果是 'global',而不是我们期望的 'mocked'。这是因为在组件内部调用 globalFunction() 时,它并没有被 Mock 控制,而是执行了原有的函数。解决这个问题的方法是在组件内部直接调用 Mock 函数:

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

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

---------- ------ ---------- -- -- -
  -----------------------------------------
  ----- ------- - -------------------- ----
  -----------------------------------------
---
展开代码
  1. Mock 会影响其他测试用例

Mock 会影响全局作用域,如果我们在一个测试用例中 Mock 了一个函数,那么这个 Mock 会影响所有后续的测试用例。这可能会导致一些意外的行为,例如一个测试用例依赖于另一个测试用例 Mock 的函数,但是这个函数在后续测试用例中被还原了,导致测试失败。

解决这个问题的方法是在每个测试用例中重新 Mock 函数,或者使用 beforeEach() 函数在每个测试用例前都重新 Mock 函数:

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

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

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

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

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

二、Mock 的 trap

  1. Mock 会覆盖原有函数的实现

Mock 会覆盖原有函数的实现,如果我们在测试用例中 Mock 了一个函数,那么它的原有实现就被覆盖了。这可能会导致一些意外的行为,例如一个测试用例依赖于另一个测试用例 Mock 的函数,但是这个函数在后续测试用例中被还原了,导致测试失败。

解决这个问题的方法是在 Mock 函数中调用原有函数的实现,而不是完全覆盖它。我们可以使用 jest.fn() 创建一个 Mock 函数,并使用 jest.fn().mockImplementation() 或者 jest.fn().mockImplementationOnce() 方法来指定 Mock 函数的实现。

例如,在下面的代码中,我们使用 jest.fn() 创建了一个 Mock 函数,然后使用 jest.fn().mockImplementation() 方法来指定 Mock 函数的实现:

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

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

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

  ---------- ------ ---------- -- -- -
    ----- ------- - -------------------- ----
    -----------------------------------------
  ---
---
展开代码
  1. Mock 会影响函数的类型检查

Mock 会影响函数的类型检查,如果我们在测试用例中 Mock 了一个函数,那么它的类型就会被改变。这可能会导致一些意外的行为,例如一个函数本来应该接收一个字符串类型的参数,但是被 Mock 后却接收了一个数字类型的参数。

解决这个问题的方法是使用 jest.requireActual() 方法来获取原有函数的类型信息。这个方法会返回原有函数的类型定义,可以用来指定 Mock 函数的参数类型和返回类型。

例如,在下面的代码中,我们使用 jest.requireActual() 方法来获取原有函数的类型定义,并使用它来指定 Mock 函数的参数类型和返回类型:

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

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

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

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

本文详细介绍了 Enzyme 中 Mock 的坑和 trap,并提供了解决方案和指导意义。在使用 Mock 时,我们需要注意作用域和影响范围,避免出现意外的行为。同时,我们也可以使用 jest.fn() 和 jest.requireActual() 方法来指定 Mock 函数的实现和类型定义,避免影响函数的类型检查。

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

纠错
反馈

纠错反馈