【问题标题】:Jest unit tests with useRoute from react-navigation使用 react-navigation 中的 useRoute 进行 Jest 单元测试
【发布时间】:2021-02-04 18:52:39
【问题描述】:

我们最近将我们的 React Native 代码库升级到了 React Navigation 的第 5 版,并且在此过程中,我们将几个组件从类组件重构为功能组件。这意味着我们正在使用像 useNavigation() 和 useRoute() 这样的钩子。

我很难弄清楚如何解决我在进行单元测试时遇到的问题。看起来导航和路线道具的状态在运行时对测试不可用。例如,我从 Jest 收到以下错误:

● <EULA /> › Rendering › should match to snapshot

    TypeError: Cannot read property 'name' of undefined

      27 |   const route = useRoute();
      28 |   const authContext = useContext(AuthContext);
    > 29 |   const isAcceptPP: boolean = route.name === "AcceptEULA";
         |                                     ^

这个错误让我相信当第 27 行在单元测试的上下文中运行时,它实际上并没有从 useRoute() 返回一个路由对象。这个错误出现在我对该文件的所有测试中。

这就是当前测试的样子,我尝试模拟 useRoute 并仅将 route 作为 props 的一部分,但这些似乎并没有起到什么作用:

import React from "react";
import { render, fireEvent, waitFor } from "@testing-library/react-native";
import { WebView } from "react-native-webview";
import { Alert } from "react-native";

import EULA from "../src/screens/EULA";
import { alertSpy } from "../src/jest/spies";

describe("<EULA />", () => {
  let props;
  let useRoute: jest.Mock;
  beforeEach(() => {
    useRoute = jest.fn();
    props = { navigation: { state: { routeName: "AcceptEULA" }, navigate: navigate }, route: { name: "AcceptEULA" } };
  });

  describe("Rendering", () => {
    it("should match to snapshot when accept EULA", async () => {
      const { toJSON, getByType } = render(<EULA {...props} />);
      await waitFor(() => getByType(WebView));
      expect(toJSON()).toMatchSnapshot();
    });

我对 Jest 还是有点陌生​​,我不确定我应该如何处理这个问题,因为路线不再是导航道具的一部分,但我可能只是想多了。

【问题讨论】:

  • 如果没有一个最小的、完整的、可重现的代码,就无法提供帮助。

标签: react-native unit-testing jestjs react-hooks react-navigation


【解决方案1】:

我认为问题在于您将模拟路由作为prop 传递,而您的测试试图使用hook 捕获路由。

我认为这可以帮助你:

import { useRoute } from "@react-navigation/core";
jest.mock("@react-navigation/core");
import EULA from "../src/screens/EULA";

describe("Rendering", () => {
  it("should match to snapshot when accept EULA", async () => {
    useRoute.mockReturnValue({
      name: "AcceptEULA"
    });
    const { toJSON, getByType } = render(<EULA />);
    ...
  });
});

【讨论】:

    猜你喜欢
    • 2018-05-08
    • 2018-02-15
    • 2020-07-24
    • 1970-01-01
    • 2017-12-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-09-06
    相关资源
    最近更新 更多