DEV Community

Cover image for Testing a simple component with React Testing Library

Testing a simple component with React Testing Library

Matti Bar-Zeev on October 22, 2021

In this post join me as I use React Testing Library to test a simple React component. Apart from applying the testing library capabilities I hope t...
Collapse
 
ftinoco profile image
Fernando Tinoco

This post saved my day, I was struggling all day with a test where I needed to write values in the autosuggest input, userEvent.type doesn't work, but with fireEvent.change it does. I don't really understand why, but my problem is solved.

New follower :)

Collapse
 
simphiwetebe profile image
SimphiweTebe

Same, I am not sure why the userEvent does not work. I was scratching my head and frustrated over this

Collapse
 
jantimon profile image
Jan Nicklas

data-testid is only for cases which are hard to solve with the recommended testing-library api..

In your case you can also use the following code instead: screen.getByRole('textbox', { placeholder: "Add word..." })

testing-playground.com/

Collapse
 
mbarzeev profile image
Matti Bar-Zeev • Edited

Yes, I am aware that this is what the recommendations suggest, but IMO tightly coupling language-based queries (byText, byLabelText, byAltText, byPlaceholderText, etc.) are more fragile and limiting when you wish to test other languages, for instance.
More so, when you write e2e automatons you find that having a non-dependent identifier makes life a lot easier. So If you're going to do that for e2e test, why not use the same data-testId for both purposes.
This is a discussion that also took place on twitter with Kent C. Dodds (twitter.com/mattibarzeev/status/14...) and I might submit a "call" just to make sure I understand what he's suggesting there.

Collapse
 
haaxor1689 profile image
Maroš Beťko

This solution seems much better. Cluttering your components with testing attributes looks like bad practice.

Collapse
 
frondor profile image
Federico Vázquez

Nice article! I'd like to add that you should use userEvent.type(input, 'matti') instead of fireEvent.change(input, {target: {value: 'matti'}});.
This way you get a better coverage and also to resemble the user interaction more closely.

Collapse
 
mbarzeev profile image
Matti Bar-Zeev

Thanks!
Yes, I also wrote that there is na option to simulatet the user typing, bit I think that firing the change event is sufficient here. Simulating the actual typing kinda crosses the border between unit and automation test for me, but sure, you can simulate the typing as well.

Collapse
 
haaxor1689 profile image
Maroš Beťko • Edited

I'm planning on getting into writing tests for a while now. Thanks for showing multiple options of this testing library. It looks pretty handy, I would liko to see it with typescript though. What I didn't like, was the data attribute related to tests in the component itself.

One thing though. I feel like the examples use way too much explicit types. Some examples like isInvalidWord: boolean or onAddClicked: MouseEventHandler<HTMLButtonElement> feel absolutely unnecessary. Also the useRef can be used much simpler.

const inputEl: RefObject<HTMLInputElement> | null = useRef(null);
// vs
const inputEl = useRef<HTMLInputElement | null>(null);
Enter fullscreen mode Exit fullscreen mode
Collapse
 
mbarzeev profile image
Matti Bar-Zeev

I hear ya.
I'm fairly new to TypeScript but not at all new to typed languages. I don't see declaring types as an optional choice. Either you're writing in a typed language or not. If you're using a typed language you should type anything which can be typed.
Nice simplification on the useRef() though ;)

Collapse
 
haaxor1689 profile image
Maroš Beťko • Edited

Typescript should be a tool that helps you and not something that hinders you by wasting your time. Even languages like C++ now provide conveniences like auto type. By omitting some explicit types to let them be implicitly deduced or simplifying them you don't give up any type safety but save your time and make development faster.

Collapse
 
geminii profile image
Jimmy

Nice example 👏
Two things :

  • sad about usage of data-testid (already use it in the past and now using directly role. It permits to improve accessibility too). Don't know if you could provide an improvement on it 🥹
  • no typescript as bonus 😭 (it could be so nice to have some tests with Typescript declaration).

Otherwise, it's a nice example provided 🙏
Thanks for it 🙂

Collapse
 
roygav profile image
roygav

Great article, informative, clear and pleasant to read, thanks!