I'm fairly new to the world of writing tests for React so forgive the possible newbie question. I've done a fair amount of research and have not found anything that covers this as yet.
I have a really simple BackButton
component, all it does is render a button and have an onClick event that goes back in the history. It uses react-router
v6 if that is helpful.
import * as React from 'react';
import Stack from '@mui/material/Stack';
import { ArrowCircleLeftOutlined } from '@mui/icons-material';
import { Link, useNavigate } from 'react-router-dom';
export default function BackButton() {
const navigate = useNavigate();
return (
<Stack direction="row" spacing={1}>
<Link onClick={() => navigate(-1)} aria-label="back" data-testid="backButton">
<ArrowCircleLeftOutlined />
</Link>
</Stack>
);
}
I've written a test for this using Testing Library but can't seem to figure out a way to see what the location changed to. window.location.href
just returns http://localhost
import React from 'react';
import { fireEvent, render, screen } from '@testing-library/react';
import { MemoryRouter } from 'react-router-dom';
import BackButton from './BackButton';
it('has a href that refers to the previous page', () => {
const initialLink = "/foo";
render(
<MemoryRouter initialEntries={[initialLink]}>
<BackButton />
</MemoryRouter>
);
const element = screen.getByTestId('backButton');
expect(element.getAttribute('href')).toBe(initialLink);
fireEvent.click(element);
// How do I test the location changed?
})
After being pointed in the direction of mocking useNavigate
(Thanks @DrewReece) I was then able to check to see how many times and how useNavigate
was called. The test I ended up with is below. I still had to use react-testing-library
so I could fire the event on the screen but very open to learning if this is not the best way to do it.
import React from 'react';
import BackButton from './BackButton';
import { MemoryRouter } from 'react-router-dom';
import { render, fireEvent, screen } from '@testing-library/react';
const mockedUseNavigate = jest.fn();
jest.mock('react-router-dom', () => ({
...jest.requireActual('react-router-dom'),
useNavigate: () => mockedUseNavigate,
}));
it('navigates to previous page on click', () => {
render(<MemoryRouter><BackButton /></MemoryRouter>);
const element = screen.getByTestId('backButton');
fireEvent.click(element);
expect(mockedUseNavigate).toBeCalledTimes(1);
expect(mockedUseNavigate).toBeCalledWith(-1);
})