Skip to main content
Course/Module 11/Topic 2 of 4Advanced

Advanced React Testing

Learn React Testing Library for testing React components in a way that resembles how users interact with your application.

90 minBy Priygop TeamLast updated: Feb 2026

RTL Philosophy

React Testing Library focuses on testing components the way users would interact with them, making tests more reliable and maintainable.

Basic Component Testing

Example
// Basic component test
import { render, screen } from '@testing-library/react';
import Button from './Button';

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

User Interactions

Example
// Testing user interactions
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: 0');
    
    fireEvent.click(button);
    
    expect(count).toHaveTextContent('Count: 1');
});

Form Testing

Example
// Testing forms
import { render, screen, fireEvent, waitFor } from '@testing-library/react';
import LoginForm from './LoginForm';

test('submits form with valid data', async () => {
    const onSubmit = jest.fn();
    render(<LoginForm onSubmit={onSubmit} />);
    
    fireEvent.change(screen.getByLabelText(/email/i), {
        target: { value: 'test@example.com' }
    });
    fireEvent.change(screen.getByLabelText(/password/i), {
        target: { value: 'password123' }
    });
    
    fireEvent.click(screen.getByRole('button', { name: /submit/i }));
    
    await waitFor(() => {
        expect(onSubmit).toHaveBeenCalledWith({
            email: 'test@example.com',
            password: 'password123'
        });
    });
});

Custom Hooks Testing

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

test('useCounter hook', () => {
    const { result } = renderHook(() => useCounter(0));
    
    expect(result.current.count).toBe(0);
    
    act(() => {
        result.current.increment();
    });
    
    expect(result.current.count).toBe(1);
});

Mini-Project: Complete Component Test Suite

Example
// Complete test suite for a complex component
import { render, screen, fireEvent, waitFor } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { BrowserRouter } from 'react-router-dom';
import UserProfile from './UserProfile';

const renderWithRouter = (component) => {
    return render(
        <BrowserRouter>
            {component}
        </BrowserRouter>
    );
};

describe('UserProfile Component', () => {
    const mockUser = {
        id: 1,
        name: 'John Doe',
        email: 'john@example.com',
        avatar: 'avatar.jpg'
    };
    
    beforeEach(() => {
        jest.clearAllMocks();
    });
    
    test('renders user information', () => {
        renderWithRouter(<UserProfile user={mockUser} />);
        
        expect(screen.getByText('John Doe')).toBeInTheDocument();
        expect(screen.getByText('john@example.com')).toBeInTheDocument();
    });
    
    test('handles edit mode toggle', async () => {
        const user = userEvent.setup();
        renderWithRouter(<UserProfile user={mockUser} />);
        
        const editButton = screen.getByRole('button', { name: /edit/i });
        await user.click(editButton);
        
        expect(screen.getByDisplayValue('John Doe')).toBeInTheDocument();
        expect(screen.getByRole('button', { name: /save/i })).toBeInTheDocument();
    });
    
    test('saves user changes', async () => {
        const onSave = jest.fn();
        const user = userEvent.setup();
        
        renderWithRouter(<UserProfile user={mockUser} onSave={onSave} />);
        
        await user.click(screen.getByRole('button', { name: /edit/i }));
        await user.clear(screen.getByDisplayValue('John Doe'));
        await user.type(screen.getByDisplayValue(''), 'Jane Doe');
        await user.click(screen.getByRole('button', { name: /save/i }));
        
        await waitFor(() => {
            expect(onSave).toHaveBeenCalledWith({
                ...mockUser,
                name: 'Jane Doe'
            });
        });
    });
});

Additional Resources

Recommended Reading

  • React Testing Library Documentation
  • Jest Testing Framework Guide
  • Testing Best Practices
  • Integration Testing Strategies

Online Resources

  • React Testing Tutorial
  • Jest Testing Examples
  • Testing Library Cheat Sheet
  • Advanced Testing Patterns
Chat on WhatsApp
Priygop - Leading Professional Development Platform | Expert Courses & Interview Prep