Skip to Content
FrontendReactIntermediate2.7 React Testing

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’s renderHook (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-event for 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