The component is connected to React Router. It renders a variable text containing a URL parameter, as well as a Link
to another location.
First we make sure the component renders a param from the initial URL. Then we check that the URL param from a new location is rendered upon clicking on the Link element, which proves that the page has successfully routed.
Alternatively, we could just test the
to
prop of the Link element. That's also fine. But this test is closer to how a user thinks: Click on a link. Did the linked page open?This type of thinking makes tests more resilient against implementation changes, like upgrading the router library to a new API.
// Hoist helper functions (but not vars) to reuse between test casesconst renderComponent = ({ userId }) => render( <MemoryRouter initialEntries={[`/users/${userId}`]}> <Route path="/users/:userId"> <UserWithRouter /> </Route> </MemoryRouter> );it('renders initial user id', async () => { // Render new instance in every test to prevent leaking state const { getByText } = renderComponent({ userId: 5 }); await waitForElement(() => getByText(/user #5/i));});it('renders next user id', async () => { // Render new instance in every test to prevent leaking state const { getByText } = renderComponent({ userId: 5 }); fireEvent.click(getByText(/next user/i)); await waitForElement(() => getByText(/user #6/i));});
// Hoist helper functions (but not vars) to reuse between test cases
const renderComponent = ({ userId }) =>
render(
<MemoryRouter initialEntries={[`/users/${userId}`]}>
<Route path="/users/:userId">
<UserWithRouter />
</Route>
</MemoryRouter>
);
it('renders initial user id', async () => {
// Render new instance in every test to prevent leaking state
const { getByText } = renderComponent({ userId: 5 });
await waitForElement(() => getByText(/user #5/i));
});
it('renders next user id', async () => {
// Render new instance in every test to prevent leaking state
const { getByText } = renderComponent({ userId: 5 });
fireEvent.click(getByText(/next user/i));
await waitForElement(() => getByText(/user #6/i));
});