How to mock React-Router-Dom hooks in Jest

How to mock React-Router-Dom hooks in Jest

To mock React-Router-Dom hooks in React you need to do the following:

  • Mock the library React-Router-Dom using jest.mock
  • Import non-mocked React-Router-Dom, so that we can use the rest of the non-mocked hooks
  • Mock the required hook (useNavigate, userParam…etc) using jest.fn

Example

The following example shows a single button that navigate the user to a different page once the button is clicked:

import React from "react";
import { useNavigate } from "react-router-dom";
import "./styles.css";

export default function App() {
  const navigate = useNavigate();

  return (
    <div>
      <button onClick={() => navigate("/post-1")}>
        Post 1 - Using useNavigate hook
      </button>
    </div>
  );
}

The navigation is done using the useNavigate hook, So in our test we need to mock the useNavigate hook and verify it has been called with the exact page route after the button click action.

Component Test

import React from "react";
import { BrowserRouter } from "react-router-dom";
import userEvent from "@testing-library/user-event";
import { screen, render } from "@testing-library/react";
import App from "./App";

// 1- Mocking the hook using jest.fn
const mockedUsedNavigate = jest.fn();

// 2- Mock the library
jest.mock("react-router-dom", () => ({

// 3- Import non-mocked library and use other functionalities and hooks
  ...(jest.requireActual("react-router-dom") as any),

// 4- Mock the required hook
  useNavigate: () => mockedUsedNavigate
}));

describe("App", () => {
  it("has a button and does navigate to other component", async () => {
    render(
      <BrowserRouter>
        <App />
      </BrowserRouter>
    );

    // Testing navigating using the button
    expect(
      screen.getByText("Post 1 - Using useNavigate hook")
    ).toBeInTheDocument();

    await userEvent.click(screen.getByText("Post 1 - Using useNavigate hook"));
    expect(mockedUsedNavigate).toHaveBeenCalledWith('/post-1');
  });
});

The above test example does the following:

  1. Create a new mocked function using jest.fn(), to be used instead of the actual useNavigate hook.
  2. Mocking the whole React-Router-Dom library.
  3. Import non-mocked React-Router-Dom library and use other functionalities and hooks that are not mocked.
  4. Replace the actual useNavigate implementation with our mocked function created in step1.

At this stage, we’ve mocked the useNavigate hook from React-Router-Dom, and it’s ready to be tested.

    // Testing navigating using the button
    expect(
      screen.getByText("Post 1 - Using useNavigate hook")
    ).toBeInTheDocument();

    await userEvent.click(screen.getByText("Post 1 - Using useNavigate hook"));
    expect(mockedUsedNavigate).toHaveBeenCalledWith('/post-1');

In the above test suite, we’ve verified that the button is existing in the DOM.

Then, we’ve simulated the user click on the button by calling userEvent.click function from React-Testing-Library on the button.

At the last step, we’ve verified that the mockedUsedNavigate function is being called the exact route /post-1.

By running the test, we should receive the following results:

How to mock React-Router-Dom hooks in Jest
How to mock React-Router-Dom hooks in Jest

Source code

Photo from Unsplash

Related Posts

How to Capture Screenshots with Puppeteer In NodeJS

How to Capture Screenshots with Puppeteer In NodeJS

To Capture Screenshots with Puppeteer: Launch a Browser Instance Navigate to the Web Page Capture the Screenshot Introduction: Puppeteer is a powerful Node.js library that allows developers…

How to Minimize Puppeteer Browser Window To Tray

How to Minimize Puppeteer Browser Window To Tray

Puppeteer is a powerful tool for automating tasks in headless or non-headless web browsers using JavaScript. While Puppeteer is often used to perform actions within a browser,…

Intercepting Responses in Node.js with Puppeteer

Intercepting Responses in Node.js with Puppeteer

Introduction: Puppeteer is a powerful Node.js library that provides a high-level API for controlling headless Chrome or Chromium browsers. It’s widely used for web scraping, automated testing,…

Mastering React Component Re-rendering in Jest

Mastering React Component Re-rendering in Jest

In this hands-on guide, we’ll explore the art of optimizing React component re-rendering within Jest tests. By combining theory with practical coding examples, you’ll gain a deep…

Eliminating Nesting Loops in React Rendering

Eliminating Nesting Loops in React Rendering

React has ushered in a new era of web application development with its component-based structure, promoting code reusability and maintainability. But as projects evolve, achieving optimal performance…

Exploring Type and Interface Usage in TypeScript

Exploring Type and Interface Usage in TypeScript

TypeScript has gained immense popularity by bridging the gap between dynamic JavaScript and static typing. Two of its fundamental features, “Type” and “Interface,” play pivotal roles in…

This Post Has 2 Comments

  1. 1.can you write a test for useActionData where the action is passed in routes?
    2.can you write one where the same action will return different data?

Leave a Reply

%d bloggers like this: