DEV Community

loading...

Test `history` in React Router

Teerasak Vichadee
・1 min read

Problem

When we use hooks useHistory of react-router-dom
How to expect the history are changes?
How to mock the history?

Solution

Don't try to expect global window.location or window.history.
Just render test component as a children of <Router>, it's require history object just create a simple Javascript object with mock on specific function (depend on your needs)

example from React Router document :p

// HomeButton.jsx
import { useHistory } from "react-router-dom";

export function HomeButton() {
  let history = useHistory();

  function handleClick() {
    history.push("/home");
  }

  return (
    <button data-testid="button" type="button" onClick={handleClick}>
      Go home
    </button>
  );
}
Enter fullscreen mode Exit fullscreen mode

the test file

// HomeButton.test.jsx
import { render, screen, act } from '@testing-library/react';
import userEvent from '@testing-library/user-event';

import { HomeButton } from './HomeButton';

describe('HomeButton', () => {
  // the test might throw an error about required properties, it's depend on your component's dependencies.
  const mockHistory = {
    push: jest.fn(),
  }

  it('should go to home after click', () => {
    await act(async () => {
      render(
        <Router history={mockHistory}>
          <HomeButton />
        </Router>
      )

      userEvent.click(screen.getByTestId('button'))
    })

    expect(mockHistory.push).toBeCalledTime(1)
    expect(mockHistory.push).toBeCalledWith("/home")
  })
})
Enter fullscreen mode Exit fullscreen mode

Discussion (0)