DEV Community

Discussion on: Enzyme or react-testing-library and why?

Collapse
yuritoledo profile image
Yuri Toledo Author

I'm learning RTL and I use enzyme. I Try to reproduce the same tests that I use on enzyme to RTL, but I cant.

For example, how could I check if all form fields was filled and compare with a object that I'll send to backend?

Collapse
lacasa profile image
𝙻𝚊𝚌𝚊𝚜𝚊

From my experience, you'll have to rethink how to test stuff most of the time. A direct conversion from Enzyme to RTL won't work.

I always try to avoid testing implementation details. I don't have much details about your example, but in RTL is quite easy to get/set fields content, then you have to find the submit button, fire the click event, and expect some data to be sent.

I found way more difficult to test render props for instance...

Thread Thread
yuritoledo profile image
Yuri Toledo Author

hmmm I see.

And its hard to find material to study, I cant understand the Kodds examples too much :/
And I hate the fact that I cant find a comp by id or name hehe

Thread Thread
lacasa profile image
𝙻𝚊𝚌𝚊𝚜𝚊

You'll find the way, no worries...

I ended up using tons of data-testid in the mocks (I try really hard to avoid them in the real code).

Thread Thread
yuritoledo profile image
Yuri Toledo Author

I wanna try to avoid using it too, but how I use 3rd party components, I can't use htmlFor for example, and I rarely use placeholder

Thread Thread
lacasa profile image
𝙻𝚊𝚌𝚊𝚜𝚊 • Edited on

If you are using 3rd party components for inputs/labels, that's perfect! You don't need to test that whatever they do internally works, you just need to test that your component does what it needs, so you can mock them.

jest.mock('ui-library/Input', () =>
  jest.fn(({value, handleChange}) => <input data-testid="input" onChange={handleChange} value={value} />)
);

it('should do magic', () => {
  const {getByTestId} = render(<Component />);

  // we test that the component is rendering
  expect(getByTestId('input').value).toBeInTheDocument();

  // we test that the component shows the proper value
  expect(getByTestId('input').value).toEqual(oldValue);

  // we test that Component can handle change events
  // (we don't care how Input does that internally)
  fireEvent.change(getByTestId('input'), newValue);
  expect(getByTestId('input').value).toEqual(newValue);
});

The code might have errors, but the I think the idea is clear enough!

Thread Thread
yuritoledo profile image
Yuri Toledo Author

Yeah, its clear, thank you bro

Thread Thread
nersoh profile image
Nelson Henrique • Edited on

"And I hate the fact that I cant find a comp by id or name hehe"

I don't know if you already figured out how to do it, but I actually can by doing, for example:

const { container } = render(Component);
expect(container.querySelector("#myid")).not.toBeNull();

Thread Thread
lacasa profile image
𝙻𝚊𝚌𝚊𝚜𝚊 • Edited on

You can create your custom selectors like this:

import { queryByAttribute, render } from '@testing-library/react';

const getByName = queryByAttribute.bind(null, 'name');

it('should...', () => {
  const { container } = render(<Component />);
  expect(getByName(container, 'the-name').toEqual(...)
})

I have some custom selectors created in a utils file (name, type, id...).