Testing Library

Testing Library

  • Docs
  • Recipes
  • Help
  • Blog

›Examples

Guides

  • Recipes
  • Which query should I use?
  • Appearance and Disappearance
  • Considerations for fireEvent

Examples

  • Codesandbox Examples
  • Input Event
  • Update Props
  • React Context
  • useReducer
  • React Intl
  • React Redux
  • React Router
  • Reach Router
  • React Transition Group
  • Modals
  • External Examples

Help

  • Learning Material
  • Contributing
Edit

Reach Router

import React from 'react'
import { render } from '@testing-library/react'
import {
  Router,
  Link,
  createHistory,
  createMemorySource,
  LocationProvider,
} from '@reach/router'
import '@testing-library/jest-dom/extend-expect'

const About = () => <div>You are on the about page</div>
const Home = () => <div>You are home</div>
const NoMatch = () => <div>No match</div>

function App() {
  return (
    <div>
      <Link to="/">Home</Link>
      <Link to="/about">About</Link>
      <Router>
        <Home path="/" />
        <About path="/about" />
        <NoMatch default />
      </Router>
    </div>
  )
}

// Ok, so here's what your tests might look like

// this is a handy function that I would utilize for any component
// that relies on the router being in context
function renderWithRouter(
  ui,
  { route = '/', history = createHistory(createMemorySource(route)) } = {}
) {
  return {
    ...render(<LocationProvider history={history}>{ui}</LocationProvider>),
    // adding `history` to the returned utilities to allow us
    // to reference it in our tests (just try to avoid using
    // this to test implementation details).
    history,
  }
}

test('full app rendering/navigating', async () => {
  const {
    container,
    history: { navigate },
  } = renderWithRouter(<App />)
  const appContainer = container
  // normally I'd use a data-testid, but just wanted to show this is also possible
  expect(appContainer.innerHTML).toMatch('You are home')

  // with reach-router we don't need to simulate a click event, we can just transition
  // to the page using the navigate function returned from the history object.
  await navigate('/about')
  expect(container.innerHTML).toMatch('You are on the about page')
})

test('landing on a bad page', () => {
  const { container } = renderWithRouter(<App />, {
    route: '/something-that-does-not-match',
  })
  // normally I'd use a data-testid, but just wanted to show this is also possible
  expect(container.innerHTML).toMatch('No match')
})

// If your route component has parameters, you'll have to change the render function a little bit
// example of a route component with parameter
const Routes = () => (
  <Router>
    <SomeComponent path="/some-component/:id" />
  </Router>
)

// render function with Router wrapper from @reach/router
function renderWithRouterWrapper(
  ui,
  { route = '/', history = createHistory(createMemorySource(route)) } = {}
) {
  return {
    ...render(
      <LocationProvider history={history}>
        <Router>{ui}</Router>
      </LocationProvider>
    ),
    history,
  }
}

test('renders the component with params', () => {
  // you'll have to declare the path prop in the component, exactly like the route
  renderWithRouterWrapper(<SomeComponent path="/some-component/:id" />, {
    // and pass the parameter value on the route config
    route: '/some-component/1',
  })
})
Last updated on 8/3/2020
← React RouterReact Transition Group →
Testing Library
Docs
Getting StartedExamplesAPIHelp
Community
BlogStack OverflowDiscord
More
StarGitHubEdit Docs on GitHubHosted by Netlify
Copyright © 2018-2020 Kent C. Dodds and contributors