@remix-run/testing
This package contains utilities to assist in unit testing portions of your Remix application. This is accomplished by mocking the Remix route modules/assets manifest output by the compiler and generating an in-memory React Router app via createMemoryRouter.
The general usage of this is to test components/hooks that rely on Remix hooks/components which you do not have the ability to cleanly mock (useLoaderData
, useFetcher
, etc.). While it can also be used for more advanced testing such as clicking links and navigating to pages, those are better suited for End-to-End tests via something like Cypress or Playwright.
To use createRemixStub
, define your routes using React Router-like route objects, where you specify the path
, Component
, loader
, etc. These are essentially mocking the nesting and exports of the route files in your Remix app:
import { createRemixStub } from "@remix-run/testing";
const RemixStub = createRemixStub([
{
path: "/",
Component: MyComponent,
loader() {
return json({ message: "hello" });
},
},
]);
Then you can render the <RemixStub />
component and assert against it:
render(<RemixStub />);
await screen.findByText("Some rendered text");
Here's a full working example testing using jest
and React Testing Library:
import { json } from "@remix-run/node";
import { useLoaderData } from "@remix-run/react";
import { createRemixStub } from "@remix-run/testing";
import {
render,
screen,
waitFor,
} from "@testing-library/react";
test("renders loader data", async () => {
// ⚠️ This would usually be a component you import from your app code
function MyComponent() {
const data = useLoaderData() as { message: string };
return <p>Message: {data.message}</p>;
}
const RemixStub = createRemixStub([
{
path: "/",
Component: MyComponent,
loader() {
return json({ message: "hello" });
},
},
]);
render(<RemixStub />);
await waitFor(() => screen.findByText("Message: hello"));
});