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.

--

--

--

I build web apps

Love podcasts or audiobooks? Learn on the go with our new app.

The Powerful Chrome Console!

Laravel Basic Move

Migrating to TypeScript

How JSON.stringify killed my express server

Creating a Nuxt.js project with Yarn workspace/Lerna Monorepo In 3 Steps

Result Build

Making a User Media Preview Component

Devlog #001: Recoloring Sprites in Unity

Slice and Append function in Golang

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
#ashcodes

#ashcodes

I build web apps

More from Medium

useState vs. useRef and useReducer: Similarities, differences, and use cases

React application

Jest tests failed when using csv-parse/sync library

Exploring more about reducers, pure functions,side-effects ,useEffect() ,async calls and context..!

From Redux Sagas to React Query