Testing 🔍
Testing protects behavior as React apps evolve. Combine unit, component, and end-to-end tests for confidence.
1) Unit Tests 🧠
- Use Jest or Vitest to test pure utilities and hooks.
import { formatCurrency } from "./formatCurrency";
test("formats numbers", () => {
expect(formatCurrency(12.5)).toBe("$12.50");
});- Keep tests focused on deterministic outputs.
- For hooks, use
@testing-library/react’srenderHook(or testing-library’s hooks utilities) to verify behavior.
2) Component Tests (React Testing Library) ⚛️
- Render components like a user would see them; query DOM via accessible roles.
import { render, screen, fireEvent } from "@testing-library/react";
import Counter from "./Counter";
test("increments count", () => {
render(<Counter />);
fireEvent.click(screen.getByRole("button", { name: "+1" }));
expect(screen.getByText(/count: 1/i)).toBeInTheDocument();
});- Use
user-eventfor realistic interactions (typing, tabbing). - Avoid brittle selectors (
data-testid) unless necessary.
3) Mocking Network Requests 🌐
- Mock fetch with
jest.spyOn(global, "fetch")or use MSW (Mock Service Worker) for high-fidelity mocks.
beforeEach(() => {
global.fetch = vi.fn(() =>
Promise.resolve({ json: () => Promise.resolve([{ id: 1, name: "Todo" }]) })
);
});- MSW intercepts real network calls via service workers, letting you reuse mocks across tests and local dev.
4) E2E Basics (Playwright/Cypress) 🧪
- Spin up the app + backend (or mocked API) and run flows end to end.
// Playwright example
import { test, expect } from "@playwright/test";
test("user can add todo", async ({ page }) => {
await page.goto("http://localhost:5173");
await page.getByLabel("New Todo").fill("Learn React");
await page.getByRole("button", { name: "Add" }).click();
await expect(page.getByText("Learn React")).toBeVisible();
});- Use CI to run E2E suites nightly or before releases.
- Keep tests independent; reset database/fixtures before each run.
Key Takeaways ✅
- Unit tests lock down pure logic; component tests exercise UI behaviors with realistic queries.
- Mock network requests to keep tests deterministic; MSW provides high-fidelity mocks.
- E2E tests verify real-world flows using Playwright or Cypress; run them less frequently but treat failures seriously.
Recap 🔄
A healthy React test pyramid mixes fast unit tests, user-centric component tests, and occasional E2E suites. Mock dependencies thoughtfully and favor queries that mirror user behavior to keep tests maintainable.
Last updated on