
Research
PyPI Package Disguised as Instagram Growth Tool Harvests User Credentials
A deceptive PyPI package posing as an Instagram growth tool collects user credentials and sends them to third-party bot services.
next-router-mock
Advanced tools
The next-router-mock package is a mock implementation of Next.js's router, designed for testing purposes. It allows developers to simulate and test routing behavior in their Next.js applications without needing to run a full Next.js server.
Mocking push method
This feature allows you to mock the push method of the Next.js router, enabling you to simulate navigation to a new route in your tests.
const { useRouter } = require('next/router');
const mockRouter = require('next-router-mock');
mockRouter.push('/new-route');
console.log(mockRouter.pathname); // Output: /new-route
Mocking query parameters
This feature allows you to mock query parameters in the Next.js router, enabling you to test components that rely on query parameters.
const { useRouter } = require('next/router');
const mockRouter = require('next-router-mock');
mockRouter.push({ pathname: '/new-route', query: { id: '123' } });
console.log(mockRouter.query.id); // Output: 123
Mocking back method
This feature allows you to mock the back method of the Next.js router, enabling you to simulate the user navigating back to the previous route.
const { useRouter } = require('next/router');
const mockRouter = require('next-router-mock');
mockRouter.push('/first-route');
mockRouter.push('/second-route');
mockRouter.back();
console.log(mockRouter.pathname); // Output: /first-route
React Router is a popular routing library for React applications. Unlike next-router-mock, which is specifically designed for mocking Next.js's router in tests, React Router provides a full-featured routing solution for React applications. It includes features like nested routes, route parameters, and more.
React Router DOM is an extension of React Router that provides DOM bindings for React applications. It is similar to next-router-mock in that it allows for routing in React applications, but it is not specifically designed for mocking purposes. Instead, it is used for actual routing in web applications.
Jest Mock is a general-purpose mocking library that can be used to mock any JavaScript module or function. While it is not specifically designed for mocking Next.js's router, it can be used to create custom mocks for any part of your application, including the Next.js router.
next-router-mock
An implementation of the Next.js Router that keeps the state of the "URL" in memory (does not read or write to the
address bar). Useful in tests and Storybook.
Inspired by react-router > MemoryRouter
.
Tested with NextJS v13, v12, v11, and v10.
Install via NPM: npm install --save-dev next-router-mock
For usage with next/navigation
jump to Usage with next/navigation Beta
next/link
For unit tests, the next-router-mock
module can be used as a drop-in replacement for next/router
:
jest.mock("next/router", () => require("next-router-mock"));
You can do this once per spec file, or you can do this globally using setupFilesAfterEnv
.
In your tests, use the router from next-router-mock
to set the current URL and to make assertions.
import { useRouter } from "next/router";
import { render, screen, fireEvent } from "@testing-library/react";
import mockRouter from "next-router-mock";
jest.mock("next/router", () => jest.requireActual("next-router-mock"));
const ExampleComponent = ({ href = "" }) => {
const router = useRouter();
return <button onClick={() => router.push(href)}>The current route is: "{router.asPath}"</button>;
};
describe("next-router-mock", () => {
it("mocks the useRouter hook", () => {
// Set the initial url:
mockRouter.push("/initial-path");
// Render the component:
render(<ExampleComponent href="/foo?bar=baz" />);
expect(screen.getByRole("button")).toHaveTextContent('The current route is: "/initial-path"');
// Click the button:
fireEvent.click(screen.getByRole("button"));
// Ensure the router was updated:
expect(mockRouter).toMatchObject({
asPath: "/foo?bar=baz",
pathname: "/foo",
query: { bar: "baz" },
});
});
});
Globally enable next-router-mock
by adding the following webpack alias to your Storybook configuration.
In .storybook/main.js
add:
module.exports = {
webpackFinal: async (config, { configType }) => {
config.resolve.alias = {
...config.resolve.alias,
"next/router": "next-router-mock",
};
return config;
},
};
This ensures that all your components that use useRouter
will work in Storybook. If you also need to test next/link
, please see the section Example: next/link
with Storybook.
In your individual stories, you might want to mock the current URL (eg. for testing an "ActiveLink" component), or you might want to log push/replace
actions. You can do this by wrapping your stories with the <MemoryRouterProvider>
component.
// ActiveLink.story.jsx
import { action } from "@storybook/addon-actions";
import { MemoryRouterProvider } from "next-router-mock/MemoryRouterProvider/next-13";
import { ActiveLink } from "./active-link";
export const ExampleStory = () => (
<MemoryRouterProvider url="/active" onPush={action("router.push")}>
<ActiveLink href="/example">Not Active</ActiveLink>
<ActiveLink href="/active">Active</ActiveLink>
</MemoryRouterProvider>
);
Be sure to import from a matching Next.js version:
import { MemoryRouterProvider } from 'next-router-mock/MemoryRouterProvider/next-13.5';
Choose from
next-13.5
,next-13
,next-12
, ornext-11
.
The MemoryRouterProvider
has the following optional properties:
url
(string
or object
) sets the current route's URLasync
enables async mode, if necessary (see "Sync vs Async" for details)onPush(url, { shallow })
onReplace(url, { shallow })
onRouteChangeStart(url, { shallow })
onRouteChangeComplete(url, { shallow })
next/link
To use next-router-mock
with next/link
, you must use a <MemoryRouterProvider>
to wrap the test component.
next/link
with React Testing LibraryWhen rendering, simply supply the option { wrapper: MemoryRouterProvider }
import { render } from "@testing-library/react";
import NextLink from "next/link";
import mockRouter from "next-router-mock";
import { MemoryRouterProvider } from "next-router-mock/MemoryRouterProvider";
it("NextLink can be rendered", () => {
render(<NextLink href="/example">Example Link</NextLink>, { wrapper: MemoryRouterProvider });
fireEvent.click(screen.getByText("Example Link"));
expect(mockRouter.asPath).toEqual("/example");
});
next/link
with EnzymeWhen rendering, simply supply the option { wrapperComponent: MemoryRouterProvider }
import { shallow } from "enzyme";
import NextLink from "next/link";
import mockRouter from "next-router-mock";
import { MemoryRouterProvider } from "next-router-mock/MemoryRouterProvider";
it("NextLink can be rendered", () => {
const wrapper = shallow(<NextLink href="/example">Example Link</NextLink>, {
wrapperComponent: MemoryRouterProvider,
});
wrapper.find("a").simulate("click");
expect(mockRouter.asPath).to.equal("/example");
});
next/link
with StorybookIn Storybook, you must wrap your component with the <MemoryRouterProvider>
component (with optional url
set).
// example.story.jsx
import NextLink from "next/link";
import { action } from "@storybook/addon-actions";
import { MemoryRouterProvider } from "next-router-mock/MemoryRouterProvider/next-13.5";
export const ExampleStory = () => (
<MemoryRouterProvider url="/initial">
<NextLink href="/example">Example Link</NextLink>
</MemoryRouterProvider>
);
This can be done inline (as above).
It can also be implemented as a decorator
, which can be per-Story, per-Component, or Global (see Storybook Decorators Documentation for details).
Global example:
// .storybook/preview.js
import { MemoryRouterProvider } from 'next-router-mock/MemoryRouterProvider';
export const decorators = [
(Story) => <MemoryRouterProvider><Story /></MemoryRouterProvider>
];
By default, next-router-mock
does not know about your dynamic routes (eg. files like /pages/[id].js
).
To test code that uses dynamic routes, you must add the routes manually, like so:
import mockRouter from "next-router-mock";
import { createDynamicRouteParser } from "next-router-mock/dynamic-routes";
mockRouter.useParser(
createDynamicRouteParser([
// These paths should match those found in the `/pages` folder:
"/[id]",
"/static/path",
"/[dynamic]/path",
"/[...catchAll]/path",
])
);
// Example test:
it("should parse dynamic routes", () => {
mockRouter.push("/FOO");
expect(mockRouter).toMatchObject({
pathname: "/[id]",
query: { id: "FOO" },
});
});
By default, next-router-mock
handles route changes synchronously. This is convenient for testing, and works for most
use-cases.
However, Next normally handles route changes asynchronously, and in certain cases you might actually rely on that
behavior. If that's the case, you can use next-router-mock/async
. Tests will need to account for the async behavior
too; for example:
it("next/link can be tested too", async () => {
render(
<NextLink href="/example?foo=bar">
<a>Example Link</a>
</NextLink>
);
fireEvent.click(screen.getByText("Example Link"));
await waitFor(() => {
expect(singletonRouter).toMatchObject({
asPath: "/example?foo=bar",
pathname: "/example",
query: { foo: "bar" },
});
});
});
useRouter()
withRouter(Component)
router.push(url, as?, options?)
router.replace(url, as?, options?)
router.route
router.pathname
router.asPath
router.query
next/link
(see Jest notes)router.events
supports:
routeChangeStart(url, { shallow })
routeChangeComplete(url, { shallow })
hashChangeStart(url, { shallow })
hashChangeComplete(url, { shallow })
PRs welcome!
These fields just have default values; these methods do nothing.
router.isReady
router.basePath
router.isFallback
router.isLocaleDomain
router.locale
router.locales
router.defaultLocale
router.domainLocales
router.prefetch()
router.back()
router.beforePopState(cb)
router.reload()
router.events
not implemented:
routeChangeError
beforeHistoryChange
For unit tests, the next-router-mock/navigation
module can be used as a drop-in replacement for next/navigation
:
jest.mock("next/navigation", () => require("next-router-mock/navigation"));
You can do this once per spec file, or you can do this globally using setupFilesAfterEnv
.
In your tests, use the router from next-router-mock
to set the current URL and to make assertions.
import mockRouter from "next-router-mock";
import { render, screen, fireEvent } from "@testing-library/react";
import { usePathname, useRouter } from "next/navigation";
jest.mock("next/navigation", () => jest.requireActual("next-router-mock/navigation"));
const ExampleComponent = ({ href = "" }) => {
const router = useRouter();
const pathname = usePathname();
return <button onClick={() => router.push(href)}>The current route is: {pathname}</button>;
};
describe("next-router-mock", () => {
it("mocks the useRouter hook", () => {
// Set the initial url:
mockRouter.push("/initial-path");
// Render the component:
render(<ExampleComponent href="/foo?bar=baz" />);
expect(screen.getByRole("button")).toHaveTextContent("The current route is: /initial-path");
// Click the button:
fireEvent.click(screen.getByRole("button"));
// Ensure the router was updated:
expect(mockRouter).toMatchObject({
asPath: "/foo?bar=baz",
pathname: "/foo",
query: { bar: "baz" },
});
});
});
1.0.2
FAQs
Mock implementation of the Next.js Router
The npm package next-router-mock receives a total of 524,647 weekly downloads. As such, next-router-mock popularity was classified as popular.
We found that next-router-mock demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Research
A deceptive PyPI package posing as an Instagram growth tool collects user credentials and sends them to third-party bot services.
Product
Socket now supports pylock.toml, enabling secure, reproducible Python builds with advanced scanning and full alignment with PEP 751's new standard.
Security News
Research
Socket uncovered two npm packages that register hidden HTTP endpoints to delete all files on command.