Do you know how to test for click events on icons? (#19)

You can with the dom-testing-library

Aw look, a cute puppy!

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 dom-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 })
);
// the mock function that triggers when iconButton is clicked.
expect(mockFunction).toHaveBeenCalled();

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.

Originally published at https://www.ashcodes.com.

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store