-
Notifications
You must be signed in to change notification settings - Fork 54
React Testing Library unittest
We Have to migrate from enzyme to RTL because React 18 has a internal breaking change that makes enzyme dead by design. React now schedule render. So we have to rewrite a bunch of tests suite (360).
But RTL came with a real difference: no access to react component, no access to state. It looks like a more end to end approach. As we still need unittest we have to find tricks to tests only one component and not the entire subset.
Also RTL is based on jsdom so there is limitations, we will try to list them.
Snapshot are nice to keep a trace of the render. Just do one per component seems enough. This is usefull to see impact when a DOM is changed for example after upgrading a library to see if the dom has changed.
Avoid doing 10 snapshots has they do not fit any tests except it('should render', () => {
As component is about responsabilities it is ok to mock underlying components or dependencies. This is not considered as a code smell ref
The goal of mock can be:
- make it easier to test the component
- gather information of state of the current component you test
First tips is to use dataset.props
:
jest.mock('../../pickers/CalendarPicker', () => {
return props => <div data-testid="CalendarPicker" data-props={JSON.stringify(props)} />;
});
// ..tests
// then
const props = JSON.parse(screen.getByTestId('CalendarPicker').dataset.props);
expect(props).toMatchObject({
manageFocus: true,
other: 'custom props',
selectedDate: '2007-01-01T23:00:00.000Z',
useUTC: false,
});
The drawback is you don't have access to function but this is often OK as function are most of the time event handler. You can add buttons to manage event handler out of the scope of your current component. But this is usefull only if the current component create this handler. if it is only a pass through it doesn't make sens to unittest it.
jest.mock('../../views/DateTimeView', () =>
jest.fn(props => (
<div data-testid="DateTimeView" data-props={JSON.stringify(props)}>
<button onClick={() => props.onTitleClick()}>Select MonthYearView</button>
</div>
)),
);