jest-typescript
Jest with TypeScript - Industry standard testing framework with 70% market share, mature ecosystem, React Testing Library integration
What this skill does
# Jest + TypeScript - Industry Standard Testing
## Overview
Jest is the industry-standard testing framework with 70% market share, providing a mature, battle-tested ecosystem for TypeScript projects. It offers comprehensive testing capabilities with built-in snapshot testing, mocking, and coverage reporting.
**Key Features**:
- ๐ **Industry Standard**: 70% market share, widely adopted
- ๐ฆ **All-in-One**: Test runner, assertions, mocks, coverage in one package
- ๐ธ **Snapshot Testing**: Built-in snapshot support for UI testing
- ๐งช **React Integration**: React Testing Library, enzyme compatibility
- ๐ง **Mature Ecosystem**: Extensive plugins, tooling, and community support
- ๐ฏ **TypeScript Support**: Full type safety via ts-jest
- ๐ **Coverage Reports**: Built-in Istanbul coverage
- ๐ **Multi-Platform**: Node.js, browser (jsdom), React Native
**Installation**:
```bash
npm install -D jest @types/jest ts-jest
npm install -D @testing-library/react @testing-library/jest-dom # For React
```
## Basic Setup
### 1. Initialize Jest Configuration
```bash
npx ts-jest config:init
```
This creates **jest.config.js**:
```javascript
module.exports = {
preset: 'ts-jest',
testEnvironment: 'node',
};
```
### 2. Manual Configuration
**jest.config.ts** (TypeScript config):
```typescript
import type { Config } from 'jest';
const config: Config = {
preset: 'ts-jest',
testEnvironment: 'node',
roots: ['<rootDir>/src'],
testMatch: ['**/__tests__/**/*.ts', '**/?(*.)+(spec|test).ts'],
moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json'],
collectCoverageFrom: [
'src/**/*.{ts,tsx}',
'!src/**/*.d.ts',
'!src/**/*.test.{ts,tsx}',
'!src/**/__tests__/**',
],
coverageThreshold: {
global: {
branches: 80,
functions: 80,
lines: 80,
statements: 80,
},
},
};
export default config;
```
### 3. TypeScript Configuration
**tsconfig.json**:
```json
{
"compilerOptions": {
"types": ["jest", "@testing-library/jest-dom"],
"esModuleInterop": true
}
}
```
**tsconfig.test.json** (test-specific):
```json
{
"extends": "./tsconfig.json",
"compilerOptions": {
"types": ["jest", "node", "@testing-library/jest-dom"]
},
"include": ["src/**/*.test.ts", "src/**/*.spec.ts", "src/**/__tests__/**"]
}
```
### 4. Package.json Scripts
```json
{
"scripts": {
"test": "jest",
"test:watch": "jest --watch",
"test:coverage": "jest --coverage",
"test:ci": "jest --ci --coverage --maxWorkers=2"
}
}
```
## Core Testing Patterns
### Basic Test Structure
```typescript
import { describe, it, expect, beforeEach, afterEach } from '@jest/globals';
describe('Calculator', () => {
let calculator: Calculator;
beforeEach(() => {
calculator = new Calculator();
});
afterEach(() => {
// Cleanup
});
it('adds two numbers correctly', () => {
const result = calculator.add(2, 3);
expect(result).toBe(5);
});
it('handles negative numbers', () => {
expect(calculator.add(-5, 3)).toBe(-2);
});
it.each([
[1, 1, 2],
[2, 3, 5],
[10, -5, 5],
])('adds %i + %i to equal %i', (a, b, expected) => {
expect(calculator.add(a, b)).toBe(expected);
});
});
```
### TypeScript Type-Safe Tests
```typescript
interface User {
id: number;
name: string;
email: string;
role: 'admin' | 'user';
}
describe('User Service', () => {
it('creates user with correct types', () => {
const user: User = {
id: 1,
name: 'Alice',
email: '[email protected]',
role: 'admin',
};
// Type-safe assertions
expect(user.id).toEqual(expect.any(Number));
expect(user.name).toEqual(expect.any(String));
expect(user.role).toMatch(/^(admin|user)$/);
});
it('validates user object shape', () => {
const user = createUser('Bob', '[email protected]');
expect(user).toMatchObject({
id: expect.any(Number),
name: 'Bob',
email: '[email protected]',
});
});
});
```
## Mocking with TypeScript
### jest.mock for Module Mocking
```typescript
import { jest } from '@jest/globals';
import { UserService } from './UserService';
import * as userApi from './api/userApi';
// Mock entire module
jest.mock('./api/userApi');
describe('UserService with Mocks', () => {
beforeEach(() => {
jest.clearAllMocks();
});
it('fetches user data', async () => {
const mockUser = { id: 1, name: 'Alice', email: '[email protected]' };
// Type-safe mock
const mockedFetchUser = jest.mocked(userApi.fetchUser);
mockedFetchUser.mockResolvedValue(mockUser);
const service = new UserService();
const user = await service.getUser(1);
expect(mockedFetchUser).toHaveBeenCalledWith(1);
expect(user).toEqual(mockUser);
});
});
```
### jest.spyOn for Method Spying
```typescript
import { jest } from '@jest/globals';
class Logger {
log(message: string): void {
console.log(message);
}
error(message: string): void {
console.error(message);
}
}
describe('Logger Spy', () => {
let logger: Logger;
let logSpy: jest.SpyInstance;
beforeEach(() => {
logger = new Logger();
logSpy = jest.spyOn(logger, 'log');
});
afterEach(() => {
logSpy.mockRestore();
});
it('tracks method calls', () => {
logger.log('Hello');
logger.log('World');
expect(logSpy).toHaveBeenCalledTimes(2);
expect(logSpy).toHaveBeenCalledWith('Hello');
expect(logSpy).toHaveBeenLastCalledWith('World');
});
it('provides custom implementation', () => {
logSpy.mockImplementation((msg: string) => {
console.log(`[CUSTOM] ${msg}`);
});
logger.log('Test');
expect(logSpy).toHaveBeenCalledWith('Test');
});
});
```
### Type-Safe Mock Functions
```typescript
import { jest } from '@jest/globals';
interface ApiResponse<T> {
data: T;
status: number;
}
type FetchUserFn = (id: number) => Promise<ApiResponse<User>>;
describe('Type-Safe Mocks', () => {
it('creates typed mock function', async () => {
const mockFetchUser = jest.fn<FetchUserFn>()
.mockResolvedValue({
data: { id: 1, name: 'Alice', email: '[email protected]', role: 'user' },
status: 200,
});
const result = await mockFetchUser(1);
expect(result.data.name).toBe('Alice');
expect(result.status).toBe(200);
expect(mockFetchUser).toHaveBeenCalledWith(1);
});
it('uses mock implementation', () => {
const mockCalculate = jest.fn<(x: number, y: number) => number>()
.mockImplementation((x, y) => x + y);
expect(mockCalculate(5, 3)).toBe(8);
expect(mockCalculate).toHaveBeenCalledWith(5, 3);
});
});
```
### Mocking Timers
```typescript
import { jest } from '@jest/globals';
describe('Timer Mocking', () => {
beforeEach(() => {
jest.useFakeTimers();
});
afterEach(() => {
jest.useRealTimers();
});
it('fast-forwards time', () => {
const callback = jest.fn();
setTimeout(callback, 1000);
jest.advanceTimersByTime(500);
expect(callback).not.toHaveBeenCalled();
jest.advanceTimersByTime(500);
expect(callback).toHaveBeenCalledTimes(1);
});
it('runs all timers', () => {
const callback = jest.fn();
setTimeout(callback, 1000);
setTimeout(callback, 2000);
jest.runAllTimers();
expect(callback).toHaveBeenCalledTimes(2);
});
it('handles intervals', () => {
const callback = jest.fn();
setInterval(callback, 1000);
jest.advanceTimersByTime(3500);
expect(callback).toHaveBeenCalledTimes(3);
jest.clearAllTimers();
});
});
```
## React Testing Library + TypeScript
### Setup for React
```bash
npm install -D @testing-library/react @testing-library/jest-dom @testing-library/user-event
npm install -D jest-environment-jsdom
```
**jest.config.ts** (React):
```typescript
import type { Config } from 'jest';
const config: Config = {
preset: 'ts-jest',
testEnvironment: 'jsdom',
setupFilesAfterEnv: ['<rootDir>/src/test/setup.ts'],
moduleNameMapper: {
'\\.(css|less|scRelated in toolchain
nextjs-core
IncludedCore Next.js patterns for App Router development including Server Components, Server Actions, route handlers, data fetching, and caching strategies
nextjs-v16
IncludedNext.js 16 migration guide (async request APIs, "use cache", Turbopack)
vitest
IncludedVitest - Modern TypeScript testing framework with Vite-native performance, ESM support, and TypeScript-first design
mcp-protocol-builder
IncludedMCP (Model Context Protocol) - Build AI-native servers with tools, resources, and prompts. TypeScript/Python SDKs for Claude Desktop integration.
golang-database-patterns
IncludedGo database integration patterns using sqlx, pgx, and migration tools like golang-migrate
sveltekit
IncludedSvelteKit - Full-stack Svelte framework with file-based routing, SSR/SSG, form actions, and adapters for deployment