How to Test React Error Boundaries
Testing Error Boundaries in React ensures your application gracefully handles runtime crashes and displays a fallback UI to users instead of a blank screen. This article provides a straightforward guide on how to test React Error Boundaries using Jest and React Testing Library, demonstrating how to simulate component errors, assert correct fallback rendering, and suppress noisy console error logs during your test runs.
The Testing Strategy
To test an Error Boundary, you must force a child component to throw an error during its render phase. Your test should then verify that: 1. The crash is intercepted by the Error Boundary. 2. The designed fallback UI (such as an error message or a redirect button) renders successfully. 3. The rest of the application does not crash.
Step-by-Step Implementation
Below is a complete example of how to test a standard React Error Boundary using Jest and React Testing Library.
1. Create a Problematic Component
First, create a dummy component that intentionally throws an error when rendered. This will act as the trigger for your Error Boundary.
const ProblemChild = () => {
throw new Error('Test Error');
};2. Write the Test Case
Wrap the ProblemChild component inside your
ErrorBoundary component within the render
function of React Testing Library.
import React from 'react';
import { render, screen } from '@testing-library/react';
import ErrorBoundary from './ErrorBoundary';
// A component that intentionally throws an error
const ProblemChild = () => {
throw new Error('Test Error');
};
describe('ErrorBoundary Component', () => {
// Suppress console.error logging for clean test output
beforeEach(() => {
jest.spyOn(console, 'error').mockImplementation(() => {});
});
afterEach(() => {
console.error.mockRestore();
});
test('should render fallback UI when a child component throws an error', () => {
render(
<ErrorBoundary fallback={<div>Something went wrong.</div>}>
<ProblemChild />
</ErrorBoundary>
);
// Assert that the fallback UI is rendered
const fallbackMessage = screen.getByText('Something went wrong.');
expect(fallbackMessage).toBeInTheDocument();
});
test('should render children when there is no error', () => {
render(
<ErrorBoundary fallback={<div>Something went wrong.</div>}>
<div>Normal Child Component</div>
</ErrorBoundary>
);
// Assert that the normal UI is rendered
const normalChild = screen.getByText('Normal Child Component');
expect(normalChild).toBeInTheDocument();
});
});Key Considerations when Testing Error Boundaries
Suppressing Console Errors
React automatically logs caught errors to the console, which can make
your test suite output look like it failed even when the tests pass.
Using
jest.spyOn(console, 'error').mockImplementation(() => {})
suppresses these logs during the test run. Remember to restore the
original console behavior in afterEach to avoid hiding
actual errors in other tests.
Testing Error Logging Handlers
If your Error Boundary sends error logs to an external service (like
Sentry or LogRocket) via componentDidCatch, you should mock
that logging function and assert that it was called with the correct
error parameters:
expect(logService.logError).toHaveBeenCalledWith(expect.any(Error));