Testing Components with React Testing Library in React JS
React Testing Library (RTL) is a popular testing library for React applications. It focuses on testing components from the perspective of the user by emphasizing interactions and rendered output rather than internal implementation details.
Why Use React Testing Library?
- Provides utilities to test components the way users interact with them.
- Encourages testing accessibility and user flows.
- Integrates seamlessly with Jest for assertions and mocking.
Setting Up React Testing Library
If you're using Create React App (CRA), React Testing Library is already set up. For a custom setup, install it using:
npm install @testing-library/react @testing-library/jest-dom
Example 1: Testing Static Component Rendering
The example below tests if a component renders correctly:
// Welcome.js
import React from 'react';
function Welcome({ user }) {
return Welcome, {user || 'Guest'}!
;
}
export default Welcome;
// Welcome.test.js
import { render, screen } from '@testing-library/react';
import Welcome from './Welcome';
test('renders welcome message for a guest', () => {
render( );
expect(screen.getByText('Welcome, Guest!')).toBeInTheDocument();
});
test('renders welcome message for a user', () => {
render( );
expect(screen.getByText('Welcome, John!')).toBeInTheDocument();
});
Example 2: Testing User Interactions
The following example tests a component with user interaction:
// Counter.js
import React, { useState } from 'react';
function Counter() {
const [count, setCount] = useState(0);
return (
Count: {count}
);
}
export default Counter;
// Counter.test.js
import { render, screen, fireEvent } from '@testing-library/react';
import Counter from './Counter';
test('increments the count when the button is clicked', () => {
render( );
const button = screen.getByText('Increment');
fireEvent.click(button);
expect(screen.getByText('Count: 1')).toBeInTheDocument();
});
Example 3: Testing Form Submissions
The example below tests form submission with a mocked function:
// LoginForm.js
import React, { useState } from 'react';
function LoginForm({ onSubmit }) {
const [username, setUsername] = useState('');
const handleSubmit = (e) => {
e.preventDefault();
onSubmit(username);
};
return (
);
}
export default LoginForm;
// LoginForm.test.js
import { render, screen, fireEvent } from '@testing-library/react';
import LoginForm from './LoginForm';
test('submits the form with the correct username', () => {
const mockSubmit = jest.fn();
render( );
const input = screen.getByPlaceholderText('Enter username');
const button = screen.getByText('Login');
fireEvent.change(input, { target: { value: 'testuser' } });
fireEvent.click(button);
expect(mockSubmit).toHaveBeenCalledWith('testuser');
});
Example 4: Testing Asynchronous Behavior
RTL provides utilities for testing asynchronous code. Here’s an example:
// FetchData.js
import React, { useEffect, useState } from 'react';
function FetchData() {
const [data, setData] = useState(null);
useEffect(() => {
fetch('https://jsonplaceholder.typicode.com/posts/1')
.then((response) => response.json())
.then((data) => setData(data));
}, []);
return (
{data ? {data.title}
: Loading...
}
);
}
export default FetchData;
// FetchData.test.js
import { render, screen, waitFor } from '@testing-library/react';
import FetchData from './FetchData';
global.fetch = jest.fn(() =>
Promise.resolve({
json: () => Promise.resolve({ title: 'Test Post' }),
})
);
test('renders fetched data after loading', async () => {
render( );
expect(screen.getByText('Loading...')).toBeInTheDocument();
await waitFor(() => expect(screen.getByText('Test Post')).toBeInTheDocument());
});
Best Practices for Testing with React Testing Library
- Focus on testing user behavior and outcomes.
- Use accessible queries like
getByText
,getByRole
, orgetByLabelText
. - Mock API calls and external dependencies to isolate components.
- Write meaningful test descriptions to explain test intent.
React Testing Library encourages best practices by focusing on user experience and interactions. By using the examples and guidelines provided, you can effectively test components in your React applications.