React Testing Library
"The more your tests resemble the way your software is used, the more confidence they can give you."

RTL docs
Some things are different πŸ₯πŸ₯πŸ₯πŸ₯πŸ₯
What do users interact with?
DOM
What should our tests interact with?
DOM
Render or do not...
...there is no "shallow."
        import { render } from '@testing-library/react';
      
        render(
          <I18nProvider>
            <GroupPreview {...defaultProps} />
          </I18nProvider>
        );
      
But you can still mock πŸ™ˆ
        jest.mock('@elastic/eui', () => ({
          ...jest.requireActual('@elastic/eui'),
          useResizeObserver: jest.fn(),
        }));
      
But... most of the time you shouldn't πŸ˜…
"The more your tests resemble the way your software is used, the more confidence they can give you."

RTL docs
No more access to sub props.
In a past life...
        component.find(DatePickerComponent).prop(β€˜onDateChange’)(newDate);
      
The bright future πŸŒ…
        userEvent.click(screen.getByRole('link', { name: 'Last five minutes' }));
      
The bright future πŸŒ…
        userEvent.click(screen.getByRole('link', { name: 'Last five minutes' }));
      
The bright future πŸŒ…
        userEvent.click(screen.getByRole('link', { name: 'Last five minutes' }));
      
The bright future πŸŒ…
        userEvent.click(screen.getByRole('link', { name: 'Last five minutes' }));
      
Asynchronous stuff
Asynchronous stuff: Enzyme
        await wrapper
          .find(`.kbnFieldButton__button`)
          .simulate('click');
        
        expect(something).toHaveBeenCalledWith(something expected);
      
FAIL
πŸ€”
        await act(async () => {
          await wrapper
          .find(`.kbnFieldButton__button`)
          .simulate('click');
        });
        
        expect(something).toHaveBeenCalledWith(something expected);
      
FAIL
🧐
        await act(async () => {
          await wrapper
          .find(`.kbnFieldButton__button`)
          .simulate('click');
        });
        
        wrapper.update();
        
        expect(something).toHaveBeenCalledWith(something expected);
      
FAIL
😠
        await act(async () => {
          await wrapper
          .find(`.kbnFieldButton__button`)
          .simulate('click');
        });
        
        wrapper.update();
        await new Promise(resolve => setTimeout(resolve, 0));
        
        expect(something).toHaveBeenCalledWith(something expected);
      
FAIL
😑
        
        jest.mock('lodash', () => {
          const original = jest.requireActual('lodash');

          return {
            ...original,
            debounce: (fn: unknown) => fn,
          };
        });
        
      
        ...
      
        await act(async () => {
          await wrapper
          .find(`.kbnFieldButton__button`)
          .simulate('click');
        });
        
        wrapper.update();
        await new Promise(resolve => setTimeout(resolve, 0));
        
        expect(something).toHaveBeenCalledWith(something expected);
      
PASS
πŸ˜…
🀨 Does this test actually mean anything?
Asynchronous stuff: RTL
        userEvent.click(screen.getByRole('link', { name: 'Last five minutes' }));
      
        expect(something).toHaveBeenCalledWith(something expected);
      
FAIL
πŸ™‚
        import { ... waitFor } from '@testing-library/react';
      
        ...
      
        userEvent.click(screen.getByRole('link', { name: 'Last five minutes' }));
      
        await waitFor(() => {
          expect(something).toHaveBeenCalledWith(something expected);
        });
      
PASS
😎
Accessing DOM elements
3 core operations
Singular (strict)
Plural
Good
Better
Best!
Interacting with the DOM
        import { ..., screen, fireEvent } from '@testing-library/react';
      
        fireEvent.click(await screen.findByText(label));
      
        elem.dispatchEvent(event);
      
"The more your tests resemble the way your software is used, the more confidence they can give you."

RTL docs
RTL πŸ€— user-event
        import { ..., screen } from '@testing-library/react';
        import userEvent from '@testing-library/user-event';
      
        userEvent.click(await screen.findByText(label));
      
RTL πŸ€— jest-dom
        expect(screen.getByTestId('button')).toBeDisabled();
        expect(screen.queryByRole('combo-box')).not.toBeInTheDocument();
      
RTL Resources
Up next in testing