Testing click events on icons with Testing Library
Do you know how to test for click events on icons with testing-library?
Recently, I came across an issue where I was unable to trigger a click event on an icon.
For a component that looks something like this,
<Icon onClick={() => { // do something }} data-testid="icon-test-id">
I was trying to simulate a click in my tests the same way I usually do with buttons, i.e.
const iconButton = getByTestId("icon-test-id");
iconButton.click(); // this didn't work
This always worked previously on button elements, but for some reason it wasn't working on the icon.
The Problem
Almost all solutions I found online were shallow rendering using enzyme to simulate a click like so,
import React from 'react';
import { shallow } from 'enzyme';
import Button from './Button';
describe('Test Button component', () => {
it('Test click event', () => {
const mockCallBack = jest.fn();
const button = shallow((<Button onClick={mockCallBack}>Ok!</Button>));
button.find('button').simulate('click');
expect(mockCallBack.mock.calls.length).toEqual(1);
});
});
While this is fine, it didn't make sense to add a whole new testing library to simulate a click event on a non-button element. Also, with the icon being an svg (and there being multiple svgs in my component) it didn't make sense to traverse down target it.
Now, should we make all clickable elements buttons? I guess that's a debate for another day. Instead I found a solution that made sense to me in the meantime.
The Solution
I used testing-library's fireEvent method to simulate the click.
So my test looked something like this,
fireEvent(
iconButton,
new MouseEvent('click', {
bubbles: true,
cancelable: true,
}),
)
expect(mockFunction).toHaveBeenCalled(); // the mock function that triggers when iconButton is clicked.
fireEvent takes in a node element (in my case the iconButton
, but I'm optimistic that it'll work with any element) and a JS event (you can read more about the MouseEvent I used here), and triggers the event on that node.
It also can work with any event, like keyboard events, other mouse events like mouse up, double-click, etc.