Reputation: 65
We recently upgraded our react native codebase to version 5 of React Navigation and along the way we refactored a couple components from class components to functional components. This means we are using hooks like useNavigation() and useRoute().
I am having a difficult time figuring out how to get around an issue that I am facing when we are doing unit testing. It would appear that the state of the navigation and route props aren't available to the test when it runs. For example, I get the following error from 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";
| ^
This error leads me to believe that when line 27 runs in the context of the unit test it isn't actually returning a route object from useRoute(). This error shows up on all of my tests for the file.
This is what the test looks like currently and I tried mocking the useRoute and just making route part of props, but these didn't seem to do much of anything:
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();
});
I am still a bit new to Jest and I'm not really sure how I am supposed to go about with this because route isn't really part of navigation prop anymore, but I may just be overthinking this.
Upvotes: 6
Views: 8073
Reputation: 783
I think the issue is that your passing the mock route as a prop
, while your test is trying to capture the route using a hook
.
I think this can help you:
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 />);
...
});
});
Upvotes: 8