Test Redirect With Jest, React-Router and React-Testing-Library
Tags: react, tdd, testing
Published: 2020-01-05 09:45:49

---
title: Test Redirect With Jest, React-Router and React-Testing-Library
published: true
date: 2020-01-04 00:00:00 UTC
tags: react, tdd, testing
canonical_url: https://www.rockyourcode.com/test-redirect-with-jest-react-router-and-react-testing-library/
---

> You've set up [react-testing-library][reacttesting] with [Jest][jest] and [react-router][reactrouter]. 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][reactrouter] for your component.

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

```js
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][reacttesting]** and [Jest][jest]?

# Create a Testing Router For react-testing-library

We can copy the code for testing react-router [straight from the documentation](https://testing-library.com/docs/example-react-router#__docusaurus).

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

```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](https://jestjs.io/docs/en/mock-functions) a function like an API call with [axios](https://www.npmjs.com/package/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:

```js
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](https://testing-library.com/docs/intro) quite helpful.  
You should give it a look.

### Inspired By

- [Authentication with Flask, React, and Docker](https://testdriven.io/courses/auth-flask-react/) (paid course by Michael Herman)

[reactrouter]: https://www.npmjs.com/package/react-router-dom
[reacttesting]: https://github.com/testing-library/react-testing-library
[jest]: https://jestjs.io/