Introduccion a React Testing Library

Intermedio | 50 min de lectura | 2024.12.30

Lo que Aprenderas en Este Tutorial

✓ Configuracion
✓ Escritura basica de pruebas
✓ Uso de diferentes queries
✓ Eventos de usuario
✓ Pruebas asincronas

Paso 1: Configuracion

npm install -D @testing-library/react @testing-library/jest-dom @testing-library/user-event jest jest-environment-jsdom

Paso 2: Prueba Basica

// Button.tsx
export function Button({ onClick, children }) {
  return <button onClick={onClick}>{children}</button>;
}

// Button.test.tsx
import { render, screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { Button } from './Button';

describe('Button', () => {
  it('renders correctly', () => {
    render(<Button>Click me</Button>);
    expect(screen.getByRole('button', { name: 'Click me' })).toBeInTheDocument();
  });

  it('calls onClick when clicked', async () => {
    const handleClick = jest.fn();
    render(<Button onClick={handleClick}>Click me</Button>);

    await userEvent.click(screen.getByRole('button'));
    expect(handleClick).toHaveBeenCalledTimes(1);
  });
});

Paso 3: Uso de Queries

// Orden de prioridad (enfoque en accesibilidad)
screen.getByRole('button', { name: 'Submit' });  // Maxima prioridad
screen.getByLabelText('Email');                   // Elementos de formulario
screen.getByPlaceholderText('Enter email');       // Placeholder
screen.getByText('Hello World');                  // Texto
screen.getByTestId('custom-element');             // Ultimo recurso

// Verificacion de existencia
screen.queryByRole('button');  // Retorna null si no existe
await screen.findByRole('button');  // Espera asincronamente

Paso 4: Pruebas de Formulario

// LoginForm.test.tsx
import { render, screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { LoginForm } from './LoginForm';

it('submits form with correct values', async () => {
  const handleSubmit = jest.fn();
  render(<LoginForm onSubmit={handleSubmit} />);

  await userEvent.type(screen.getByLabelText('Email'), 'test@example.com');
  await userEvent.type(screen.getByLabelText('Password'), 'password123');
  await userEvent.click(screen.getByRole('button', { name: 'Login' }));

  expect(handleSubmit).toHaveBeenCalledWith({
    email: 'test@example.com',
    password: 'password123'
  });
});

Paso 5: Pruebas Asincronas

// UserList.test.tsx
import { render, screen, waitFor } from '@testing-library/react';
import { UserList } from './UserList';

it('displays users after loading', async () => {
  render(<UserList />);

  expect(screen.getByText('Loading...')).toBeInTheDocument();

  await waitFor(() => {
    expect(screen.getByText('Alice')).toBeInTheDocument();
  });

  expect(screen.queryByText('Loading...')).not.toBeInTheDocument();
});

Paso 6: Mocks

// Mock de API
jest.mock('./api', () => ({
  fetchUsers: jest.fn().mockResolvedValue([
    { id: 1, name: 'Alice' }
  ])
}));

// Mock de componente
jest.mock('./Header', () => ({
  Header: () => <div data-testid="mock-header">Header</div>
}));

Resumen

React Testing Library recomienda escribir pruebas desde la perspectiva del usuario. Escribe pruebas utilizando queries que consideren la accesibilidad.

← Volver a la lista