2

i start to learning react testing library a few days ago and i dont know how to make my tests works with react router v6. I have this two test below:

  describe('testing login page', () => {
  test('veryfy inputs and buttons in login page', () => {
    render(
      <MemoryRouter initialEntries={['/']}>
        <Routes>
          <Route path="/" element={<LoginPage />} />
        </Routes>
      </MemoryRouter>,
    );
    const userInput = screen.getByRole('textbox');
    expect(userInput).toBeInTheDocument();
  describe('testing Mine Page', () => {
  test('check table components', () => {
    render(
      <MemoryRouter initialEntries={['/mina']}>
        <Routes>
          <Route path="/mina" element={<MineTable />} />
        </Routes>
      </MemoryRouter>,
    );
    const pageTitle = screen.getByRole('heading', { name: /mina/i });
    expect(pageTitle).toBeInTheDocument();
  });

Only the first test works, the second don't render the page MineTable, keeps rendering the last page Login. It's like the history of the first test render remains. Someone can help me? I want to test every page component of my application.

6
  • Is there a reason you need to test your UI components on a route? Why can't you test MineTable alone? Commented Mar 11, 2022 at 1:22
  • When i try to test MineTable alone i still having the same error. Only the test of <LoginPage /> works,. When i try to test the component <MineTable /> the render function of the react-testing-library not works and keeps rendering the LoginPage component instead the MineTable component Commented Mar 11, 2022 at 11:46
  • What does an isolated test for the MineTable component have to do with any other test rendering the LoginPage or any other component? Commented Mar 11, 2022 at 16:20
  • When i try test isolated i got this Error: useNavigate() may be used only in the context of a <Router> component.Jest Commented Mar 11, 2022 at 16:39
  • So you only need to render the component into a ReactTree that has a router above it providing a routing context. There's no need to render Routes and Route components. You are using RTL so you can provide a wrapper to the render test utility. Would you like an example? Commented Mar 11, 2022 at 18:06

1 Answer 1

4

Since it seems that MineTable uses a useNavigate hook it needs a routing context provided to it higher in the ReactTree that it is being rendered into.

You only need to provide a routing context, there's no need to render routes and such. For this, you can wrap the component under test directly with the MemoryRouter.

describe('testing Mine Page', () => {
  test('check table components', () => {
    render(
      <MemoryRouter>
        <MineTable />
      </MemoryRouter>,
    );
    const pageTitle = screen.getByRole('heading', { name: /mina/i });
    expect(pageTitle).toBeInTheDocument();
  });
});

In fact, this pattern of needing to provide context is so common that RTL has a wrapper option you can use to provider a wrapper component that provides all the contexts a component uses, i.e. routing, themes, redux, locale translations, etc...

Example:

const RouterWrapper = ({ children }) => (
  <MemoryRouter>
    {children}
  </MemoryRouter>
);

...

import { RouterWrapper } from '../path/to/RouterWrapper';

describe('testing Mine Page', () => {
  test('check table components', () => {
    render(<MineTable />, { wrapper: RouterWrapper });
    const pageTitle = screen.getByRole('heading', { name: /mina/i });
    expect(pageTitle).toBeInTheDocument();
  });
});

See custom render for more details.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.