import { describe, it, expect, vi } from "vitest";
import { render, screen } from "@testing-library/react";
import userEvent from "@testing-library/user-event";
import { ErrorBoundary } from "./ErrorBoundary";
const ThrowError = ({ shouldThrow }: { shouldThrow: boolean }) => {
if (shouldThrow) {
throw new Error("Test error");
}
return
Content
;
};
describe("ErrorBoundary", () => {
it("renders children when there is no error", () => {
render(
);
expect(screen.getByText("Content")).toBeInTheDocument();
});
it("renders error UI when child throws", () => {
const consoleError = vi.spyOn(console, "error").mockImplementation(() => {});
render(
);
expect(screen.getByText("Something went wrong")).toBeInTheDocument();
expect(screen.getByText(/Test error/)).toBeInTheDocument();
consoleError.mockRestore();
});
it("resets error when reset button is clicked", async () => {
const consoleError = vi.spyOn(console, "error").mockImplementation(() => {});
const user = userEvent.setup();
const { rerender } = render(
);
expect(screen.getByText("Something went wrong")).toBeInTheDocument();
await user.click(screen.getByRole("button", { name: /Reset Component/i }));
rerender(
);
expect(screen.getByText("Content")).toBeInTheDocument();
consoleError.mockRestore();
});
it("uses custom fallback when provided", () => {
const consoleError = vi.spyOn(console, "error").mockImplementation(() => {});
const customFallback = (error: Error, resetError: () => void) => (
Custom error: {error.message}
);
render(
);
expect(screen.getByText("Custom error: Test error")).toBeInTheDocument();
expect(screen.getByText("Custom Reset")).toBeInTheDocument();
consoleError.mockRestore();
});
it("logs error to console", () => {
const consoleError = vi.spyOn(console, "error").mockImplementation(() => {});
render(
);
expect(consoleError).toHaveBeenCalled();
consoleError.mockRestore();
});
});