6

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.

1
  • Can't help without a minimal, complete, reproducible code. Commented Oct 22, 2020 at 4:09

1 Answer 1

8

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 />);
    ...
  });
});
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.