---
id: example-react-router
title: React Router
---
```jsx
// app.js
import React from 'react'
import {Link, Route, Switch, useLocation} from 'react-router-dom'
const About = () =>
You are on the about page
const Home = () => You are home
const NoMatch = () => No match
export const LocationDisplay = () => {
const location = useLocation()
return {location.pathname}
}
export const App = () => (
)
```
```jsx
// app.test.js
import {render, screen} from '@testing-library/react'
import userEvent from '@testing-library/user-event'
import {createMemoryHistory} from 'history'
import React from 'react'
import {Router} from 'react-router-dom'
import '@testing-library/jest-dom'
import {App, LocationDisplay} from './app'
test('full app rendering/navigating', () => {
const history = createMemoryHistory()
render(
,
)
// verify page content for expected route
// often you'd use a data-testid or role query, but this is also possible
expect(screen.getByText(/you are home/i)).toBeInTheDocument()
const leftClick = {button: 0}
userEvent.click(screen.getByText(/about/i), leftClick)
// check that the content changed to the new page
expect(screen.getByText(/you are on the about page/i)).toBeInTheDocument()
})
test('landing on a bad page', () => {
const history = createMemoryHistory()
history.push('/some/bad/route')
render(
,
)
expect(screen.getByText(/no match/i)).toBeInTheDocument()
})
test('rendering a component that uses useLocation', () => {
const history = createMemoryHistory()
const route = '/some-route'
history.push(route)
render(
,
)
expect(screen.getByTestId('location-display')).toHaveTextContent(route)
})
```
## Reducing boilerplate
1. You can use the `wrapper` option to wrap a `MemoryRouter` around the
component you want to render.
`MemoryRouter` works when you don't need access to the history object itself
in the test, but just need the components to be able to render and
navigate.
If you _do_ need to change the history, you could use `BrowserRouter`.
```jsx
import {MemoryRouter} from 'react-router-dom'
test('full app rendering/navigating', () => {
render(, {wrapper: MemoryRouter})
// verify page content for expected route
expect(screen.getByText(/you are home/i)).toBeInTheDocument()
})
```
2. If you find yourself adding Router components to your tests a lot, you may
want to create a helper function that wraps around `render`.
```jsx
// test utils file
const renderWithRouter = (ui, {route = '/'} = {}) => {
window.history.pushState({}, 'Test page', route)
return render(ui, {wrapper: BrowserRouter})
}
```
```jsx
// app.test.js
test('full app rendering/navigating', () => {
renderWithRouter()
expect(screen.getByText(/you are home/i)).toBeInTheDocument()
const leftClick = {button: 0}
userEvent.click(screen.getByText(/about/i), leftClick)
expect(screen.getByText(/you are on the about page/i)).toBeInTheDocument()
})
test('landing on a bad page', () => {
renderWithRouter(, {route: '/something-that-does-not-match'})
expect(screen.getByText(/no match/i)).toBeInTheDocument()
})
test('rendering a component that uses useLocation', () => {
const route = '/some-route'
renderWithRouter(, {route})
expect(screen.getByTestId('location-display')).toHaveTextContent(route)
})
```