React Router
Este exemplo demonstra a React Router v6. Para versões anteriores consulte abaixo.
// app.js
import React from 'react'
import {Link, Route, Routes, useLocation} from 'react-router-dom'
const About = () => <div>You are on the about page</div>
const Home = () => <div>You are home</div>
const NoMatch = () => <div>No match</div>
export const LocationDisplay = () => {
const location = useLocation()
return <div data-testid="location-display">{location.pathname}</div>
}
export const App = () => (
<div>
<Link to="/">Home</Link>
<Link to="/about">About</Link>
<Routes>
<Route path="/" element={<Home />} />
<Route path="/about" element={<About />} />
<Route path="*" element={<NoMatch />} />
</Routes>
<LocationDisplay />
</div>
)
// app.test.js
import {render, screen} from '@testing-library/react'
import userEvent from '@testing-library/user-event'
import React from 'react'
import '@testing-library/jest-dom'
import {App, LocationDisplay} from './app'
import {BrowserRouter, MemoryRouter} from 'react-router-dom'
test('full app rendering/navigating', async () => {
render(<App />, {wrapper: BrowserRouter})
const user = userEvent.setup()
// verificar o conteúdo da página para rota padrão
expect(screen.getByText(/you are home/i)).toBeInTheDocument()
// verificar o conteúdo da página para a rota esperada depois da navegação
await user.click(screen.getByText(/about/i))
expect(screen.getByText(/you are on the about page/i)).toBeInTheDocument()
})
test('landing on a bad page', () => {
const badRoute = '/some/bad/route'
// usar "<MemoryRouter>" quando quiseres controlar manualmente a história
render(
<MemoryRouter initialEntries={[badRoute]}>
<App />
</MemoryRouter>,
)
// verificar a navegação para a rota "no match"
expect(screen.getByText(/no match/i)).toBeInTheDocument()
})
test('rendering a component that uses useLocation', () => {
const route = '/some-route'
// usar "<MemoryRouter>" quando quiseres controlar manualmente a história
render(
<MemoryRouter initialEntries={[route]}>
<LocationDisplay />
</MemoryRouter>,
)
// verificar se a exibição da localização está apresentada
expect(screen.getByTestId('location-display')).toHaveTextContent(route)
})
Reduzindo o prato cozido
- Se encontrares-te a ti mesmo adicionando muitos componentes de Router aos
teus testes, talvez queiras criar uma função auxiliar que envolva em torno de
render
.
// ficheiro de utilitário de teste
const renderWithRouter = (ui, {route = '/'} = {}) => {
window.history.pushState({}, 'Test page', route)
return {
user: userEvent.setup(),
...render(ui, {wrapper: BrowserRouter}),
}
}
// app.test.js
test('full app rendering/navigating', async () => {
const {user} = renderWithRouter(<App />)
expect(screen.getByText(/you are home/i)).toBeInTheDocument()
await user.click(screen.getByText(/about/i))
expect(screen.getByText(/you are on the about page/i)).toBeInTheDocument()
})
test('landing on a bad page', () => {
renderWithRouter(<App />, {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(<LocationDisplay />, {route})
expect(screen.getByTestId('location-display')).toHaveTextContent(route)
})
Testing Library e a React Router v5
// app.js
import React from 'react'
import {Link, Route, Switch, useLocation} from 'react-router-dom'
const About = () => <div>You are on the about page</div>
const Home = () => <div>You are home</div>
const NoMatch = () => <div>No match</div>
export const LocationDisplay = () => {
const location = useLocation()
return <div data-testid="location-display">{location.pathname}</div>
}
export const App = () => (
<div>
<Link to="/">Home</Link>
<Link to="/about">About</Link>
<Switch>
<Route exact path="/" component={Home} />
<Route path="/about" component={About} />
<Route component={NoMatch} />
</Switch>
<LocationDisplay />
</div>
)
Nos teus testes, passe o objeto da história globalmente para o componente de
Router. Nota: a React Router v5
apenas funciona com History v4,
então certifica-te de que tens a versão correta de history
instalada.
// 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} from './app'
// React Router v5
test('full app rendering/navigating', async () => {
const history = createMemoryHistory()
render(
<Router history={history}>
<App />
</Router>,
)
const user = userEvent.setup()
// verificar o conteúdo da página para a rota
// frequentemente usarias uma "data-testid" ou consulta de rótulo,
// mas isto também é possível
expect(screen.getByText(/you are home/i)).toBeInTheDocument()
await user.click(screen.getByText(/about/i))
// verificar se o conteúdo mudou para a nova página
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(
<Router history={history}>
<App />
</Router>,
)
expect(screen.getByText(/no match/i)).toBeInTheDocument()
})