React Testing Library: Checkboxes and events
Published: ....
Last modified: ....
Share this post on BlueskySee discussion on Bluesky
TL;DR
If you're testing a checkbox input element with React Testing Library, you'll
want to fire a click
event on the checkbox not a change
event!
Read on to find out how I discovered this!
I was recently refactoring about 70 individual Enzyme-based unit tests across our design system codebase at work to swap it for React Testing Library, and encountered an odd quirk that I figured I'd document on my blog.
I was converting some tests for one of our Checkbox Table components, a component that allows users to select individual rows or the entire page of results shown within a table. The previous tests were quite extensive, the entire file was well over 1200 lines of code covering many different and difficult edge cases.
As I went through I converted one of the tests that was asserting on an
onChange
handler being properly called when one of the checkboxes was
selected, the previous test code looked something like:
const handleChange = jest.fn();
const wrapper = mount(<CheckboxTable onChange={handleChange} />);
wrapper
.find(`[data-enzyme-id="header-checkbox"]`)
.simulate('change', { target: { checked: true } });
expect(handleChange).toHaveBeenCalledTimes(1);
So I started converting as I had other tests within the codebase:
const handleChange = jest.fn();
render(<CheckboxTable onChange={handleChange} />);
fireEvent.change(screen.getByTestId('header-checkbox'), {
target: { checked: true },
});
expect(handleChange).toHaveBeenCalledTimes(1);
However, the test started failing!
I started scratching my head after debugging this for about 30 minutes without
making much traction on the failing test, in fact I was about to comment the
test out and return to it in a follow up ticket but then I did one last google
search and stumbled upon
this stackoverflow result,
linked from there was this issue comment noting that for checkbox elements, we
actually want to fire a click
event instead of a change
event!
So I went back to my test and updated it one last time to the following:
const handleChange = jest.fn();
render(<CheckboxTable onChange={handleChange} />);
fireEvent.click(screen.getByTestId('header-checkbox'));
expect(handleChange).toHaveBeenCalledTimes(1);
and the test started passing!
Tags:
Related Posts
Development
Published: ....
I recently launched a rewrite and redesign of this personal website, I figured I'd talk a bit about the changes and new features that I added along the way!
Published: ....
A quick tip outlining how to provide specific TypeScript type definitions for a local module!
Published: ....
Slicing software: why vertical is better than horizontal.
Published: ....
What if you could author an entire web application in a single file?
Published: ....
Is it a good or a bad thing to offload writing code to AI agents and Large Language Models?
Published: ....
A brief look at Import Maps and package.json#imports to support isomorphic JavaScript applications!
Published: ....
A collection of tech talks that I regularly re-watch and also recommend to everyone!
Published: ....
Some features and functionality that I'd like within a React Server Component compatible framework.
Published: ....
A (running) collection of Bluesky tips, tools, packages, and other misc things!
Published: ....
How to generate a custom Ghostty theme based on any iterm2 theme!
Published: ....
A rough mental model for how you should be leveraging AI as a tool for your own growth
Published: ....
Even more thoughts on dogfooding!
Published: ....
The secret to excellent product teams is using your own product, and often!
Published: ....
(Ab)using Git as yet another tool for thought!
Published: ....
A quick look at the applications and tools that I (generally) use day to day for web development!
Published: ....
There are a variety of different markdown "standards" out there, and sometimes they're not all that consistent
Published: ....
There's a common gotcha when creating Web Request and Response instances with Headers!
Published: ....
Feature toggles are often underused by most software development teams, and yet offer so much value during not only feature development but also refactors
Published: ....
A quick introduction to my new side project, hohoro. An incremental JS/TS library build tool!
Published: ....
webpack, and tools built on it like Next.js, don't support true dynamic imports, but I found a way to trick the system!
Published: ....
I've been using a variety of AI tools as of late, I figured I'd document the ones I'm primarily using!
Published: ....
I've started to use Cloudflare to manage my domains for several side projects, have had to jump through the same hooks multiple times that I figured I should document them here!
Published: ....
Revising my previous blog post on React Error Boundaries and my preferred go-to implementation!
Published: ....
Two neat tricks for enhancing your site's favicon!
Published: ....
The various risks and pitfalls of open source software run by corporations.
Published: ....
A monorepo template for managing a library and documentation together.
Published: ....
How we solved an almost show-stopping production bug, and how you can avoid it in your own projects.
Published: ....
When did semver major changes become so scary?
Published: ....
No I don't mean those Milano cookies you keep taking from the office snack wall either (although you should probably stop snacking on those as often as well).
Published: ....
Pair programming can be good sometimes - but not all the time
Published: ....
A few quick thoughts on burn out and taking a break
React
Published: ....
A quick tip to implementing CSS theming that's compatible with Server Side Rendered applications!
Published: ....
A quick way to handle resetting internal state in components when a parent form is submitted!
Published: ....
Some features and functionality that I'd like within a React Server Component compatible framework.
Published: ....
React components have a fundamental contract that is often unstated in their implementation, and you should know about it!
Published: ....
Replace that old useState and useEffect combo for a new and better option!
Published: ....
Revising my previous blog post on React Error Boundaries and my preferred go-to implementation!
Published: ....
A few thoughts on using Suspense with GraphQL to optimize application data loading
Published: ....
A few thoughts on managing complex UI component state within React
Published: ....
A quick overview of the new lifecycle methods introduced in React 16.3