Enzyme 的 React Native 适配器问题与解决方案

在使用 React Native 进行前端开发时,测试是一个不可避免的问题。而 Enzyme 是一个流行的 React 测试工具,它提供了许多方便的 API 来测试 React 组件。然而,Enzyme 在 React Native 上的适配器存在一些问题,本文将探讨这些问题并提供解决方案。

问题描述

Enzyme 的适配器可以使用户在使用 Enzyme 时与不同的 React 实现(如 React DOM、React Native)进行交互。然而,React Native 并不是用浏览器渲染的,所以对于一些浏览器特性,如 DOM 等,Enzyme 的测试并不能同样适用于 React Native。即使是类似于 mount()shallow() 这样的基本操作,在 React Native 上也有所不同。

具体来说,以下是 Enzyme 在 React Native 上的主要问题:

  1. Enzyme 的适配器在运行 React Native 建立的应用程序时会崩溃。
  2. divspanform 等标签在 React Native 上并不存在。Enzyme 在适配器中定义了这些浏览器特有的标签,但在 React Native 上并不起作用。
  3. Enzyme 的 simulate() 方法无法模拟原生事件,如 onPress
  4. Enzyme 的某些选择器可能无法运行在 React Native 上,例如 :first-child
  5. React Native 需要一个设备或模拟器才能运行,这使得测试的速度非常缓慢。

解决方案

1. 使用 React Native TestUtils

React Native 提供了自己的测试库:React Native TestUtils。这个库提供了一些专门为 React Native 设计的测试工具,用于解决 Enzyme 在 React Native 上的一些限制。这些工具不需要设备或模拟器,可以直接在本地运行。

React Native TestUtils 提供了类似于 Enzyme 的 shallow()mount() 方法,以及一些由于 React Native 特性而新增的方法。例如,createRenderer() 方法是一个轻量级的渲染器,它能快速渲染组件并返回一个轻量级的 JavaScript 对象,方便我们进行进一步的测试。

以下代码是一个使用 React Native TestUtils 的例子:

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

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

使用 createRenderer() 方法可以得到一个渲染器,使用 render() 方法可以渲染组件,使用 getRenderOutput() 方法可以获取渲染结果。你可以使用 Jest 的 toMatchSnapshot() 方法来生成组件的快照并进行比较。

2. 替换 Enzyme 的适配器

如果你已经熟悉了 Enzyme 的 API,而且希望继续使用它来测试 React Native 组件,那么你可以替换它的适配器。第三方开发者已经写了一些 React Native 适配器,例如:

  • enzyme-to-json-react-native: 将 Enzyme 渲染的组件转换成一个 JSON 对象,以方便我们进行 JavaScript 对象比较测试。
  • enzyme-react-native-adapter: 提供与 React Native 的适配器,适配器本身还是非常基础的。可以使用 expect() 来比较渲染的结果。
  • enzyme-native-touch-events: 添加了 tap()swipe() 等原生事件的 Emulate,旨在让 React Native 的测试更加自然。

如果你对自定义适配器比较感兴趣,可以尝试自己实现。

3. 模拟原生事件

React Native 中的事件与浏览器中的事件略有不同,所以 Enzyme 同时也不能与它们进行交互。

幸运的是,我们可以使用一个第三方库:react-native-testing-library,它提供了能够与 Enzyme 配合使用的方法,可以模拟这些原生事件。

以下是如何使用 react-native-testing-library 来模拟原生事件:

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

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

这里的 fireEvent.press() 方法模拟了 onPress 事件,可以快速触发组件中的函数并对其进行测试。

4. 使用更加本地化的选择器

你可以使用基于属性的选择器,例如 getByTestId()。在组件中,你可以将每个组件都有一个唯一的 testID,用于测试和识别组件。以下是如何在组件中设置 testID

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

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

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

在测试用例中,你可以使用 getByTestId() 方法来访问这些元素:

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

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

使用 testID 可以使测试用例更简单、更清晰,而且不受 HTML 标签的影响。

结论

本文介绍了 Enzyme 在 React Native 上的一些适配器问题,并提供了解决方案。你可以选择使用 React Native TestUtils 来测试组件,也可以自定义适配器,并使用第三方库来模拟原生事件。最后,使用 testID 选择器可以使测试更本地化。

来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/670f2a6c5f55128102632242