I'm using react-router V6 and trying to test the new feature of useOutletContext. my testing library is testing-library/react and I'm not sure how to pass the Context data in the test.
In the TSX component, I'm getting the data with the hook of react-router:
const { data } = useOutletContext<IContext>()
I need something like:
test("render outlet context data view", async () => {
const { getByTestId } = render(
<MockedProvider mocks={[mockData]} context={myContextData}>
<ContextDataView />
</MockedProvider>
)
the MockedProvider tag is from @apollo/client/testing
the context={myContextData} part is what i need
Instead of mocking useOutletContext I used composition and React Router's MemoryRouter to mimic the behaviour of the real app.
I created a RenderRouteWithOutletContext component that should be used to wrap the component you're testing.
// RenderRouteWithOutletContext.tsx
import { ReactNode } from 'react';
import { MemoryRouter, Outlet, Route, Routes } from 'react-router-dom';
interface RenderRouteWithOutletContextProps<T = any> {
context: T;
children: ReactNode;
}
export const RenderRouteWithOutletContext = <T,>({
context,
children,
}: RenderRouteWithOutletContextProps<T>) => {
return (
<MemoryRouter>
<Routes>
<Route path="/"element={<Outlet context={context as T} />}>
<Route index element={children} />
</Route>
</Routes>
</MemoryRouter>
);
};
And in your test file:
// YourComponent.test.tsx
import { screen, cleanup, render } from '@testing-library/react';
import { describe, expect, it, afterEach } from 'vitest';
import { RenderRouteWithOutletContext } from './RenderRouteWithOutletContext';
const mockOutletContextData: any = {
foo: 'bar',
};
afterEach(() => {
cleanup();
});
describe('PersonOverview', () => {
it('should render as expected', () => {
render(
<RenderRouteWithOutletContext context={mockOutletContextData}>
<YourComponent />
</RenderRouteWithOutletContext>,
);
const component = screen.getByTestId('component-test-id');
expect(component).toBeInTheDocument();
});
});
Notice I'm using Vitest above but the Jest version of this is almost exactly the same.
This solution is great because it is very similar to how your app is actually used.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With