Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Testing navigate of reach router with react-testing library

An app that uses Reach Router. Has two pages, apage and bpage rendering APage and BPage
Apage has a heading and button. When the button is clicked, app navigates to bpage.

App.js

import { Router, navigate } from "@reach/router";

export default function AppWithRouter() {


  const APage = () => {

    const handle = () => {
       navigate('bpage')
    }

    return(
      <div>
        <h1>A Page</h1>
      <button onClick={handle}>Sign In</button>
      </div>
    )   

  }

  const BPage = () => (<div><h1>B Page</h1>BPage</div>)


  return (
      <Router>
        <APage path="/apage" />
        <BPage path="/bpage" />
      </Router>
  );
}

Using @testing-library/react for testing this navigation from apage to bpage using the text content of the heading.

Based on https://testing-library.com/docs/example-reach-router

renderwithRouter.js

export default function renderWithRouter(ui, route = "/") {
  let source = createMemorySource(route);
  let history = createHistory(source);

  return {
    ...render(<LocationProvider history={history}>{ui}</LocationProvider>),
    history
  };
}

My test for the navigation

App.test.js

test('click navigates to b page', async () => {


  const { getByRole  } = renderWithRouter(<App />,  '/apage')

  fireEvent.click(getByRole("button"));

  await wait(() => {
    expect(getByRole('heading')).toHaveTextContent(/b page/i)
  });

});

Fails giving

 Expected element to have text content:
      /b page/i
    Received:
      A Page

How so I test for this navigation?

like image 908
Shorn Jacob Avatar asked Oct 28 '25 17:10

Shorn Jacob


1 Answers

Simply just mock @reach/router navigate function

import { navigate } from '@reach/router'
import * as React from 'react'
import { render, fireEvent } from 'react-testing-library'
import PageA from './PageA'

jest.mock('@reach/router', () => ({
  navigate: jest.fn(),
}))

describe('Page A', () => {
  it('Should navigate from Page A to Page B', () => {
    const { getByText } = render(<Page A />)
    fireEvent.click(getByText(/Sign In/i))
    expect(navigate).toHaveBeenCalledTimes(1)
    expect(navigate).toHaveBeenCalledWith('/bpage')
  })
})

As we believe if navigate function called with correct path will navigate to Page B, example here

like image 159
Nelson Frank Avatar answered Oct 31 '25 06:10

Nelson Frank



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!