Part 5.2 — Setting Up Jest, Testing Library & Test Environment
Before you write a single frontend test, your tooling needs to disappear into the background.
If setup is fragile or confusing, developers avoid testing altogether.
In this post, you’ll set up a clean, predictable Jest environment for a React + TypeScript app—one that mirrors real usage without leaking implementation details.
1. Install Testing Dependencies
From your React project root:
pnpm add -D jest @types/jest ts-jest @testing-library/react @testing-library/jest-dom @testing-library/user-eventThese give you:
Jest test runner
DOM testing helpers
realistic user interaction simulation
2. Configure Jest for TypeScript + React
Create jest.config.ts:
import type { Config } from 'jest';
const config: Config = {
testEnvironment: 'jsdom',
setupFilesAfterEnv: ['<rootDir>/src/test/setup.ts'],
moduleFileExtensions: ['ts', 'tsx', 'js'],
testMatch: ['**/*.spec.tsx', '**/*.test.tsx'],
transform: {
'^.+\\.(ts|tsx)$': 'ts-jest',
},
};
export default config;This configuration is explicit and predictable.
3. Add Global Test Setup
Create src/test/setup.ts:
import '@testing-library/jest-dom';This adds matchers like:
expect(button).toBeDisabled();
expect(text).toBeInTheDocument();These match how users perceive the UI.
4. Configure Module Aliases (If Used)
If your app uses path aliases:
import Button from '@/components/Button';Map them in Jest:
moduleNameMapper: {
'^@/(.*)$': '<rootDir>/src/$1',
},Add this inside jest.config.ts.
5. Mock Browser APIs Missing in jsdom
jsdom doesn’t implement everything.
Common mocks:
Object.defineProperty(window, 'matchMedia', {
writable: true,
value: jest.fn().mockImplementation(() => ({
matches: false,
addListener: jest.fn(),
removeListener: jest.fn(),
})),
});Put these in setup.ts.
Only mock what breaks your tests—nothing more.
6. Mock fetch Globally
Your React app talks to REST APIs.
Tests should not.
Add to setup.ts:
global.fetch = jest.fn();Later, you’ll mock responses per test.
7. Environment Variables for Tests
Create .env.test:
VITE_API_URL=http://localhost:4000Tell Jest to load it:
import 'dotenv/config';Place this at the top of setup.ts.
This ensures your API layer behaves consistently.
8. Add pnpm Test Scripts
In package.json:
"scripts": {
"test": "jest",
"test:watch": "jest --watch",
"test:ci": "jest --runInBand"
}These mirror backend testing conventions.
9. Verify Setup with a Simple Test
Create App.test.tsx:
import { render, screen } from '@testing-library/react';
import App from './App';
it('renders the app', () => {
render(<App />);
expect(screen.getByText(/welcome/i)).toBeInTheDocument();
});Run:
pnpm testIf this passes, your environment is ready.
10. Common Setup Pitfalls
If tests fail immediately, check:
missing jsdom environment
incorrect testMatch patterns
path alias mismatches
unmocked browser APIs
fetch not mocked
environment variables missing
Fix these once—never repeatedly per test.
11. Keep Setup Boring
The best test setup is:
short
boring
invisible
Avoid clever abstractions here.
The complexity belongs in tests—not configuration.
12. Summary
You now have:
Jest configured for React + TypeScript
React Testing Library wired correctly
global DOM matchers
fetch mocking
environment variable support
pnpm scripts aligned with CI
In Part 5.3, you’ll write real component and hook tests—covering UI state, async flows, and user interactions the right way.
Related
Part 7.5 — Build Optimization with Vite: Code Splitting & Env Handling
Vite makes development fast by default. This post shows how to make production builds just as intentional—lean bundles, predictable envs, and code that ships only when needed.
Part 7.4 — Performance Hooks: useMemo, useCallback & useDeferredValue
Performance hooks are scalpels, not band-aids. This post teaches you how to use them intentionally—only where they solve real problems.
Part 7.3 — Custom Hooks as Architecture: Patterns & Pitfalls
Custom hooks aren’t just helpers. Used well, they define architectural seams in your React app. Used poorly, they hide complexity and make refactoring painful.
Comments