~3 hours Intermediate Jest · Vitest · RTL · Mocking
Overview
Testing is the foundation of reliable software. This tutorial covers the
testing pyramid, writing unit tests with Jest and Vitest, testing React
components with React Testing Library, and mocking dependencies with spies
and mocks. You'll learn to build a comprehensive test suite that catches
bugs before they reach production.
Why this matters:
Tests give you confidence to refactor, catch regressions, and ship features
faster. A good test suite is the safety net of any professional codebase.
1. The Testing Pyramid
The testing pyramid is a strategy for balancing test types:
Unit Tests (Base): Fast, isolated tests of individual functions or
components. Many tests.
Integration Tests (Middle): Tests that verify interactions between
components or services.
E2E Tests (Top): Full application tests that simulate real user
interactions. Few tests.
Best practice: Write more unit tests than integration tests,
and more integration tests than E2E tests. This gives you fast feedback and
high confidence.
2. Jest Fundamentals
Jest is the most popular testing framework for JavaScript/TypeScript.
# Installation
npm install --save-dev jest @types/jest
npm install --save-dev ts-jest # for TypeScript
// math.test.ts
import { describe, expect, it } from '@jest/globals';
function add(a: number, b: number): number { return a + b; }
function multiply(a: number, b: number): number { return a * b; }
describe('Math operations', () => {
it('adds two numbers correctly', () => {
expect(add(2, 3)).toBe(5);
expect(add(-1, 1)).toBe(0);
expect(add(0, 0)).toBe(0);
});
it('multiplies two numbers correctly', () => {
expect(multiply(2, 3)).toBe(6);
expect(multiply(-1, 5)).toBe(-5);
});
});
// component.test.tsx (Vitest)
import { describe, it, expect } from 'vitest';
import { render, screen } from '@testing-library/react';
import { Button } from './Button';
describe('Button component', () => {
it('renders with the provided label', () => {
render();
expect(screen.getByText('Click me')).toBeTruthy();
});
});
Vitest vs Jest: Vitest is faster (especially with Vite),
has built‑in ESM support, and a Jest‑compatible API. Jest is more mature
with a larger ecosystem.
4. React Testing Library
React Testing Library (RTL) is the official testing library for React.
It encourages testing components as users would interact with them.
// Mock an entire module
jest.mock('axios', () => ({
get: jest.fn(() => Promise.resolve({ data: [] })),
post: jest.fn(() => Promise.resolve({ data: {} })),
}));
// Mock a specific function
jest.mock('./utils', () => ({
...jest.requireActual('./utils'),
formatDate: jest.fn(() => '2026-09-01'),
}));
Quiz
Question 1
In the testing pyramid, which type of test is the most abundant?
E2E Tests
Integration Tests
Unit Tests
Smoke Tests
Show answer
C. Unit Tests. They are the fastest and cheapest to write and run.
Question 2
Which function in React Testing Library finds an element by its text
content?
getByTestId
getByText
getByRole
getByLabel
Show answer
B. getByText.
Question 3
What is the purpose of jest.fn()?
To run a test function
To create a mock function for testing
To skip a test
To configure Jest
Show answer
B. To create a mock function for testing.
Exercises
Exercise 1
Write Jest tests for a calculateTotal function that takes an
array of prices and returns the sum. Include edge cases (empty array, negative numbers).
Sample answer
function calculateTotal(prices: number[]): number {
return prices.reduce((sum, price) => sum + price, 0);
}
describe('calculateTotal', () => {
it('returns sum of positive prices', () => {
expect(calculateTotal([10, 20, 30])).toBe(60);
});
it('returns correct sum with negative prices', () => {
expect(calculateTotal([10, -5, 20])).toBe(25);
});
it('returns 0 for empty array', () => {
expect(calculateTotal([])).toBe(0);
});
});
Exercise 2
Write a React Testing Library test for a TodoList component
that renders a list of todos and allows adding new todos.
Sample answer
import { render, screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { TodoList } from './TodoList';
describe('TodoList', () => {
it('renders initial todos', () => {
render(
);
expect(screen.getByText('Buy milk')).toBeTruthy();
expect(screen.getByText('Walk dog')).toBeTruthy();
});
it('adds a new todo when Add button is clicked', async () => {
const user = userEvent.setup();
render(
);
const input = screen.getByPlaceholderText('Add a todo');
await user.type(input, 'Learn testing');
const addBtn = screen.getByText('Add');
await user.click(addBtn);
expect(screen.getByText('Learn testing')).toBeTruthy();
});
});
Homework
Homework 1
Write unit tests for the backend API endpoints of your capstone project
using Jest and Supertest. Include tests for GET, POST, PUT, and DELETE operations with
mocked database calls.
Sample outline
Setup: Jest with Supertest for Express API testing.
Mock database: Mock Prisma/TypeORM methods.
Tests: GET /api/products (success, not found), POST
/api/products (success, validation error), PUT /api/products/:id, DELETE
/api/products/:id.
Coverage: Aim for >80% coverage on critical paths.
Mini‑Project
Comprehensive Test Suite
Build a comprehensive test suite for a full‑stack task management
application:
Backend: Jest + Supertest for API endpoints
Frontend: Vitest + React Testing Library for components
At least 15 unit tests
At least 5 integration tests
Mock external dependencies (database, API calls)
Sample outline
Backend tests: Task CRUD, validation, error handling.
Frontend tests: TaskList component, TaskForm component, API
hooks.
Integration tests: Full flow from UI to API (with mocked API).
Coverage: Run jest --coverage and aim for 80%+.
Tutorial Summary
You learned the fundamentals of unit and integration testing: the testing
pyramid, Jest and Vitest frameworks, React Testing Library for component
testing, and mocking/spying techniques. These skills are essential for
building reliable, maintainable applications with high confidence.
Key takeaway: Testing is not a chore — it's an investment
in code quality and developer productivity. A good test suite catches bugs
early and gives you the confidence to refactor and ship features quickly.