Chapter 7: React Testing Library
Chapter 7 of 15
Chapter 7: React Testing Library
7.1 Component Testing
React Testing Library focuses on testing components from the user's perspective, not implementation details.
import { render, screen, fireEvent } from '@testing-library/react';
import Counter from './Counter';
test('increments counter on button click', () => {
render(<Counter />);
const button = screen.getByRole('button', { name: /increment/i });
const count = screen.getByText(/count:/i);
expect(count).toHaveTextContent('Count: 0');
fireEvent.click(button);
expect(count).toHaveTextContent('Count: 1');
});
7.2 Query Methods
// getBy - throws if not found (use for required elements)
screen.getByRole('button');
screen.getByText('Submit');
screen.getByLabelText('Email');
// queryBy - returns null if not found (use for optional elements)
screen.queryByText('Error message');
// findBy - returns promise (use for async elements)
await screen.findByText('Data loaded');
// getAllBy - returns array (use for multiple elements)
screen.getAllByRole('listitem');
7.3 Testing User Interactions
import { render, screen, fireEvent, waitFor } from '@testing-library/react';
test('handles form submission', async () => {
const handleSubmit = jest.fn();
render(<Form onSubmit={handleSubmit} />);
const emailInput = screen.getByLabelText('Email');
const submitButton = screen.getByRole('button', { name: /submit/i });
fireEvent.change(emailInput, { target: { value: 'test@example.com' } });
fireEvent.click(submitButton);
await waitFor(() => {
expect(handleSubmit).toHaveBeenCalledWith({
email: 'test@example.com'
});
});
});
7.4 Testing Async Operations
import { render, screen, waitFor } from '@testing-library/react';
import { rest } from 'msw';
import { setupServer } from 'msw/node';
const server = setupServer(
rest.get('/api/user', (req, res, ctx) => {
return res(ctx.json({ name: 'John' }));
})
);
beforeAll(() => server.listen());
afterEach(() => server.resetHandlers());
afterAll(() => server.close());
test('loads and displays user data', async () => {
render(<UserProfile userId="1" />);
expect(screen.getByText('Loading...')).toBeInTheDocument();
await waitFor(() => {
expect(screen.getByText('John')).toBeInTheDocument();
});
});