question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

[Feature] Add feature to allow mocking useRouter in Next.js for component testing

See original GitHub issue

If the component uses useRouter() hook, tests will fail because the hook will be null/undefined.

Jest has jest.spyOn to mock it (reference - https://jamespotz.github.io/blog/how-to-mock-userouter). It would be helpful to have something similar here.

Issue Analytics

  • State:closed
  • Created a year ago
  • Comments:5 (3 by maintainers)

github_iconTop GitHub Comments

3reactions
MindaugasMateikacommented, Jun 8, 2022

Given component

import { useRouter } from 'next/router'

const LanguageSwitch = () => {
  const router = useRouter()
  const { locales, locale: activeLocale } = router
  const otherLocales = locales?.filter(locale => locale !== activeLocale)

  return (
    // component implementation which uses router values
  )
}

export default LanguageSwitch

the test

test('renders language switch', async ({ mount }) => {
  const component = await mount(<LanguageSwitch />)
})

will result in:

    undefined: TypeError: Cannot destructure property 'locales' of 'router$1' as it is null.

What I would like to do, is mock what router would return in the test:

test('renders language switch', async ({ mount }) => {
  // mock router locales values for example so it would render component with those values
  const component = await mount(<LanguageSwitch />)
})

With Jest, it seems is possible to mock what the router would return on test by test basis (like in blog example I posted earlier)

2reactions
pavelfeldmancommented, Jul 12, 2022

Once the patch above lands, you should be able to do the following:

// index.js
import router from 'next/router';
import { beforeMount, afterMount } from '@playwright/experimental-ct-react/hooks';

beforeMount(async ({ hooksConfig }) => {
  // Before mount, redefine useRouter to return mock value from test.
  router.useRouter = () => hooksConfig.router;
});
// test.spec.jsx
// Pass mock value from test into `beforeMount`.
await mount(<App></App>, {
  hooksConfig: {
    route: {
      query: {page: 1, per_page: 10},
      asPath: '/posts'
    }
  }
});
Read more comments on GitHub >

github_iconTop Results From Across the Web

mocking useRouter (just basics) with react testing library (4/6)
In this episode , I create the navbar & product component while writing 3 tests and :1. creating advanced nav links ,2. displaying...
Read more >
Unit Testing Next.js Router - useRouter - YouTube
In this video we will unit- test components that use the Next. js useRouter hook.We will also see how to have unit- tests...
Read more >
Mocking NextJS router events with Jest - Stack Overflow
Based on that, I was able to put together the working solution below: jest.mock('next/router', () => ({ useRouter() { ...
Read more >
next-router-mock - npm
Mock implementation of the Next.js Router. ... Useful in tests and Storybook. ... Dynamic Routes; Sync vs Async; Supported Features.
Read more >
How to mock Next router with Jest - DEV Community ‍ ‍
I give a long explanation including examples and tests after. ... components/List.js import { useRouter } from 'next/router' function ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found