const mockPush = jest.fn();
jest.mock("next/navigation", () => ({
useRouter: () => ({ push: mockPush }),
usePathname: () => "/dashboard",
}));
test("goes to settings", async () => {
const user = userEvent.setup();
render(<Sidebar />);
await user.click(screen.getByRole("button", { name: /settings/i }));
expect(mockPush).toHaveBeenCalledWith("/settings");
});
Mock next/navigation and return the hooks you need, then test the component's behaviour.
Why you must mock: outside a running Next.js app there's no App Router context. So these hooks fail in Jest or Vitest.
How to mock:
- Mock the module with
jest.mock('next/navigation', ...), orvi.mockin Vitest. - Make
useRouterreturn an object with apushmock you can assert on. - Make
usePathnamereturn the path for this test.
Then test behaviour:
- Render the component.
- Click a link or button with user-event.
- Assert
pushwas called with the right URL. - Or assert the active nav item has
aria-current='page'for the mocked path.
Use the official next/jest config, or the Vitest setup from the Next docs. Then SWC (Next's compiler), CSS and image imports work. For real navigation between pages, use Playwright.
- There is no App Router context in Jest or Vitest.
- Mock the
next/navigationhooks. - Assert
router.pushcalls, or UI that depends on the pathname. - Use the
next/jestconfig so the project compiles in tests. - Real navigation between pages belongs in E2E tests.
Read more