I'm trying to verify that a certain route is called after clicking a link that is generated after an async api call. I tested for the occurrence of the link and the correct href attribute beforehand and now want to simulate a user click on the react NavLink (mocking the methods that should be called by the click).
It seems neither history.push() nor handleClick() are being called by the fireEvent. I always get this error:
Error: expect(jest.fn()).toHaveBeenCalled()
Expected number of calls: >= 1
Received number of calls: 0
I tried adding the mouse button and bubbling (according to Test : Click (fireEvent.click) on Link in react-router-dom with react-testing-library doesn't trigger and other posts), without success. Here's the code:
import {findByTestId, fireEvent, render, screen, waitFor} from '@testing-library/react';
import { MemoryRouter } from "react-router-dom";
import { createMemoryHistory } from 'history';
import Card from "./Card";
test('click on card leads to newgame/gameName route', async () => {
const history = createMemoryHistory();
history.push = jest.fn();
render(<MemoryRouter history={history}><Card element={{name: "3ts", title: "3Ts", description: "Tic Tac Toe"}}/></MemoryRouter>);
const card = await screen.findByTestId('card-link');
expect(card).toHaveAttribute('href', '/newGame/3ts');
card.handleClick = jest.fn(); // I tried this after history.push didn't seem to work
fireEvent(card, new MouseEvent('click', {bubbles: true})); // I tried adding bubbling after I read another user's situation where this helped.
expect(card.handleClick).toHaveBeenCalled();
expect(history.push).toHaveBeenCalled();
})
If you want to test a single component in a MemoryWrapper you have to configure some Routes as shown in the docu. It depends on your testing goal but if you have a NavLink in your Card component that routes to "aGame" url your test could look like this:
test('click card and jump to agame', async () => {
//arrange
render(<MemoryRouter>
<Routes>
<Route path="/" element={<Card
element={
{
name: "aName",
title: "a Title",
description: "A description",
}
}
/>}/>
<Route path="/aGame/:something" element={<NewGame/>}/>
</Routes>
</MemoryRouter>);
let navLink = await screen.findByTestId('card-link');
//act
fireEvent.click(navLink);
//assert
let aGameDiv = screen.getByTestId('agame');
expect(aGameDiv).toBeInTheDocument();
});
If you want to test your routing setup, you should test this in App.js or wherever the routing setup happens.