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
- Authentication with Flask, React, and Docker (paid course by Michael Herman)