Testing Error Boundaries in React

Error boundary tests verify that rendering failures produce the intended fallback UI and recovery behavior. A useful test checks both the boundary's failure path and the user-visible result, rather than merely confirming that an exception occurred.

In React, an error boundary is a component that catches certain errors thrown while rendering its descendant tree and displays fallback UI instead of allowing the affected subtree to render normally. Tests should therefore exercise the boundary through a child component that deliberately throws during rendering.

With React Testing Library, the main assertion should usually target what the user sees: the fallback heading, message, retry control, or other recovery UI. The test can suppress or otherwise account for expected error logging so the test output remains readable.

Recovery behavior deserves a separate assertion when the boundary supports it. For example, clicking a retry button might reset boundary state and cause the child tree to render successfully. This verifies that the boundary is not merely hiding a failure but provides the intended recovery mechanism.

Error boundaries do not catch every kind of failure. In particular, errors from event handlers and many asynchronous callbacks require different handling, so a test that throws from a button event is not equivalent to a rendering-error test. Tests should deliberately reproduce the failure mode that the boundary is designed to handle.

When testing an application-level boundary, keep the intentionally failing component small and deterministic. This makes the test communicate the contract clearly: a descendant rendering failure should result in the specified fallback and, when supported, a predictable recovery path.

Key points

Interview questions

How would you test a React error boundary?

I would render the boundary around a small component that intentionally throws during rendering. Then I would assert that the expected fallback UI is present using user-facing queries such as `getByRole`. If the test environment logs the expected error, I would suppress that noise in a controlled way. If the boundary supports recovery, I would add a separate assertion for the recovery path.

Why should an error-boundary test assert the fallback UI instead of only expecting an exception?

The boundary exists to change how a rendering failure is presented to the user, so the important contract is the resulting UI. Simply expecting an exception can miss cases where the boundary renders the wrong fallback, renders nothing, or fails to recover correctly. A user-facing assertion also makes the test less coupled to the boundary's internal state implementation.

What kinds of errors are not caught by React error boundaries?

Error boundaries are intended for errors occurring in supported React rendering and lifecycle paths of their descendant tree. They do not serve as a general-purpose replacement for handling errors in event handlers, arbitrary asynchronous callbacks, or server-side rendering. Those cases need their own error-handling mechanisms. A good test suite should therefore reproduce the same failure category that the boundary is designed to handle.

How would you test recovery after an error boundary displays its fallback?

I would first establish the failure state with a deterministic child that throws. Then I would interact with the fallback's retry or reset control and arrange for the child to render successfully on the next attempt. Finally, I would assert that the fallback disappears and the recovered content is visible. This verifies the complete state transition rather than only the initial error path.