React Testing Best Practices in 2020

The React testing landscape has shifted dramatically. In 2018, Enzyme was the standard, allowing developers to manipulate component internals (state, props). In 2020, React Testing Library (RTL) is the undisputed champion. The philosophy “The more your tests resemble the way your software is used, the more confidence they can give you” drives this shift.

Enzyme (Implementation Details) vs RTL (User Behavior)

ActionEnzyme (Do NOT use)React Testing Library (Do use)
Selectionwrapper.find('button')screen.getByRole('button', {name: /submit/i})
Statewrapper.setState({ open: true })fireEvent.click(button)
Assertionexpect(wrapper.state('open')).toBe(true)expect(screen.getByText('Content')).toBeVisible()

Writing a Robust Test

import { render, screen, waitFor } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import Login from './Login';

test('shows error when login fails', async () => {
  render(<Login />);
  
  // Interact like a user
  userEvent.type(screen.getByLabelText(/username/i), 'baduser');
  userEvent.type(screen.getByLabelText(/password/i), 'wrongpass');
  userEvent.click(screen.getByRole('button', { name: /sign in/i }));
  
  // Wait for async effect
  await waitFor(() => {
    expect(screen.getByRole('alert')).toHaveTextContent(/invalid credentials/i);
  });
});

Testing Hooks

To test custom hooks in isolation, use renderHook from @testing-library/react-hooks.

import { renderHook, act } from '@testing-library/react-hooks';
import useCounter from './useCounter';

test('should increment counter', () => {
  const { result } = renderHook(() => useCounter());

  act(() => {
    result.current.increment();
  });

  expect(result.current.count).toBe(1);
});

Key Takeaways

  • Stop testing implementation details (state, class methods).
  • Query by accessibility roles (getByRole) to ensure inclusive apps.
  • Use user-event for more realistic interaction simulation.

Discover more from C4: Container, Code, Cloud & Context

Subscribe to get the latest posts sent to your email.

Leave a comment

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.