使用 react-navigation 中的 useRoute 进行 Jest 单元测试
Posted
技术标签:
【中文标题】使用 react-navigation 中的 useRoute 进行 Jest 单元测试【英文标题】:Jest unit tests with useRoute from react-navigation 【发布时间】: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 还是有点陌生,我不确定我应该如何处理这个问题,因为路线不再是导航道具的一部分,但我可能只是想多了。
【问题讨论】:
如果没有一个最小的、完整的、可重现的代码,就无法提供帮助。 【参考方案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 />);
...
);
);
【讨论】:
以上是关于使用 react-navigation 中的 useRoute 进行 Jest 单元测试的主要内容,如果未能解决你的问题,请参考以下文章
react-navigation:从标题中的按钮导航到不同的屏幕
向@react-navigation/drawer 组件发送道具