When testing Next.js components, useRouter can be tricky. If you do not mock it, tests may fail or become hard to control.
This guide shows a simple pattern that works in most Jest setups.
Basic router mock
const push = jest.fn();
jest.mock('next/router', () => ({
useRouter: () => ({
pathname: '/products',
query: { page: '1' },
asPath: '/products?page=1',
push,
replace: jest.fn(),
prefetch: jest.fn(),
}),
}));
Now components that read route values or call push are testable.
Assert navigation behavior
it('navigates to checkout', () => {
render(<CheckoutButton />);
fireEvent.click(screen.getByRole('button', { name: /checkout/i }));
expect(push).toHaveBeenCalledWith('/checkout');
});
Dynamic route test example
Update mock values for a specific test:
(useRouter as jest.Mock).mockReturnValue({
pathname: '/posts/[slug]',
query: { slug: 'hello-world' },
push: jest.fn(),
});
This is useful when component behavior depends on route params.
App Router note (Next 13+)
If your code uses next/navigation instead of next/router, mock useRouter, usePathname, and useSearchParams from that package instead.
Same idea, different import path.