You’ve set up react-testing-library with Jest and react-router. You want to check that a component successfully redirects to another page. But how?

Your React application comes with a protected route. If a user is not authenticated, the app should redirect the user to the login screen.

You’ve managed to set up react-router-dom for your component.

For example, here’s an excerpt from a UserStatus.jsx component that only an authenticated user should be able to access:

import React, { Component } from 'react'
import { Redirect } from 'react-router-dom'
import axios from 'axios'

class UserStatus extends Component {
  // some state, etc.
  // ... code here

  // the parent component handles the authentication
  // and passes down a boolean flag
  render() {
    if (!this.props.isAuthenticated) {
      return <Redirect to="/login" />
    }
    return <div>/* JSX here */</div>
  }
}

export default UserStatus

How can we test the Redirect with react-testing-library and Jest?

Create a Testing Router For react-testing-library

We can copy the code for testing react-router straight from the documentation.

Create a new file, for example, setupTests.js:

import React from 'react'
import { Router } from 'react-router-dom'
import { render } from '@testing-library/react'
import { createMemoryHistory } from 'history'

function renderWithRouter(
  ui,
  {
    route = '/',
    history = createMemoryHistory({ initialEntries: [route] }),
  } = {}
) {
  return {
    ...render(<Router history={history}>{ui}</Router>),
    history,
  }
}

export default renderWithRouter

Create a Test File And Use the Testing Router

You might need to mock a function like an API call with axios.
That’s where jest.mock('axios') comes into play.

You’ll definitely need the fake testing router that we created earlier.

Here’s the test file for UserStatus.jsx: import renderWithRouter from setupTests.js and use it like so:

import React from 'react'
import { cleanup, wait } from '@testing-library/react'
import renderWithRouter from '../../setupTests'
import '@testing-library/jest-dom/extend-expect'
import axios from 'axios'

import UserStatus from '../UserStatus'

afterEach(cleanup)

jest.mock('axios')

// test for what happens when authenticated
// ... some code here

// test for the redirect
describe('when unauthenticated', () => {
  axios.get.mockImplementation(() =>
    Promise.resolve({
      data: { status: 'fail' },
    })
  )

  const props = {
    isAuthenticated: false,
  }

  it('redirects when authToken invalid', async () => {
    const { history } = renderWithRouter(<UserStatus {...props} />)
    await wait(() => {
      expect(axios).toHaveBeenCalled()
    })
    expect(history.location.pathname).toEqual('/login')
  })
})

And now?

I found the documentation for react-testing-library quite helpful.
You should give it a look.

Inspired By