React Native 中使用 Enzyme 测试组件报错解决方案

阅读时长 8 分钟读完

React Native 是一种广泛使用的仿原生应用的跨平台开发框架,而 Enzyme 是一个流行的 React 测试库,常用于在 React Native 上测试组件。 但是,使用 Enzyme 测试 React Native 组件时,有时会遇到以下错误:

这个错误信息通常表示同一测试中添加了相同的组件,但使用不同的名称。本文解释了这个错误的原因,并提供了解决方案以及可能的后续修补措施。

原因

问题的根源在于,Enzyme 本质上是通过更改 React 全局 React.Component.prototype 对象,来模拟组件树中的构造函数,并建立一个组件层次结构,其中所有的真实组件被替换为包装组件,Enzyme 为它们添加一组生命周期方法,用于跟踪组件的挂载、更新、卸载等过程。

这意味着,如果在同一个测试中,多次使用 mount()shallow() 方法来构建相同的组件,并使用不同的变量名,Enzyme 将尝试重复添加该组件。

解决方案

为了解决此错误,我们需要强制 React 重新加载所有组件,以确保 Enzyme 对组件使用的类和其他属性在每次测试之间得到重置。我们可以通过以下步骤完成:

  1. 引入 react-test-renderer

  2. 使用 create() 方法新建一个 React 渲染器实例,并使用 createNativeComponent() 方法强制重新加载组件:

    在这个例子中,我们假定我们的组件名称是 App,它位于相对路径../path/to/App 中,于是我们引入此文件并重新创建组件,通过 createNativeComponent() 方法调用通知 React 强制重新加载组件。

  3. 在测试之后,卸载并清除渲染器:

后续修补措施

虽然上述解决方案很好,但如果您在复杂的测试套件中使用 Enzyme,您可能会遇到挑战:需要重复使用许多组件,而每次测试之间重新加载每个组件都会变得很麻烦。

解决此问题的一种方法是,引入一个将所有组件清除出 Enzyme 内部的列表("保护"列表)的功能,以防止重复添加相同的组件,如下所示。

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

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

在这里,我们遍历 Enzyme 中所有的组件树节点,将查找 ViewText 这样被认为是 "保护" 的组件,如果有其他被保护的组件,可以在列表 protectedChildren 或纯 name 匹配上增加。在清除保护列表之后,我们可以使用 mount()shallow() 方法安全地重复多次测试。

示例代码

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

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

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

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

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

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

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

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

结论

Enzyme 是 React 测试的顶级选择之一,然而,在 React Native 中使用 Enzyme 测试组件时,会遇到“Cannot add a component XXX when a component YYY has already been added”这个小问题,而本文提供了解决方案和后续修补措施,以确保我们可以使用 Enzyme 安全和有效地测试 React Native 应用程序的组件。

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

纠错
反馈