Broken Mind
Broken Mind

Reputation: 541

How to test Router.push with Jest/React

Im still new to unit tests and im struggling to understand how i could test/mock a push from a router,

<Tab label="Members" alt="Members" onClick={() => Router.push('/members')}/>

the above line is what i need to test but how could i? would i create a fake end point and then test the onClick?

Upvotes: 12

Views: 27648

Answers (3)

Guilherme Samuel
Guilherme Samuel

Reputation: 549

I was receiving an TypeError: Cannot read property 'push' of undefined triny to mock a push of useRouter. This solution worked for me:

  1. First mock the useRouter
import { useRouter } from "next/router";

jest.mock("next/router", () => ({
  useRouter: jest.fn(),
}));
  1. And then use like this inside your test block
const push = jest.fn();

(useRouter as jest.Mock).mockImplementation(() => ({
  push,
}));

userEvent.click(screen.getByRole("button", { name: 'Move to another route' }));
expect(push).toHaveBeenCalledWith("/your-expected-route");

Found this answer here: https://github.com/vercel/next.js/issues/7479#issuecomment-778586840

Upvotes: 10

Washington Braga
Washington Braga

Reputation: 1813

In my case, I was using useRouter from next/router and I solved it using the following approach:


import { useRouter } from 'next/router'

jest.mock('next/router', () => ({
  __esModule: true,
  useRouter: jest.fn()
}))

describe('XXX', () => {
  it('XXX', () => {
    const mockRouter = {
      push: jest.fn() // the component uses `router.push` only
    }

    (useRouter as jest.Mock).mockReturnValue(mockRouter)

    expect(mockRouter.push).toHaveBeenCalledWith('/hello/world')
  })
})

Original answer: https://github.com/vercel/next.js/issues/7479#issuecomment-626297880

Upvotes: 11

Andreas K&#246;berle
Andreas K&#246;berle

Reputation: 110922

The easiest thing would be to mock the router like this

import Router from 'next/router'
jest.mock('next/router', ()=> ({push: jest.fn()}))

after simulate the click on Tab you can check for the call like this

expect(Router.push).toHaveBeenCalledWith('/members')

Upvotes: 18

Related Questions