Part 4: API Testing and Contract Testing
Introduction
REST API Testing Fundamentals
Example: User Management API
// src/api/user-controller.ts
import { Request, Response, NextFunction } from 'express';
import { UserService } from '../services/user-service';
import { z } from 'zod';
const CreateUserSchema = z.object({
email: z.string().email(),
name: z.string().min(2).max(100),
password: z.string().min(8),
});
export class UserController {
constructor(private readonly userService: UserService) {}
async createUser(req: Request, res: Response, next: NextFunction) {
try {
const validation = CreateUserSchema.safeParse(req.body);
if (!validation.success) {
return res.status(400).json({
error: 'Validation failed',
details: validation.error.errors,
});
}
const user = await this.userService.createUser(validation.data);
return res.status(201).json({
id: user.id,
email: user.email,
name: user.name,
createdAt: user.createdAt,
});
} catch (error) {
if (error instanceof Error) {
if (error.message.includes('already exists')) {
return res.status(409).json({ error: error.message });
}
}
next(error);
}
}
async getUser(req: Request, res: Response, next: NextFunction) {
try {
const { id } = req.params;
const user = await this.userService.getUserById(id);
return res.status(200).json({
id: user.id,
email: user.email,
name: user.name,
createdAt: user.createdAt,
});
} catch (error) {
if (error instanceof Error && error.message.includes('not found')) {
return res.status(404).json({ error: error.message });
}
next(error);
}
}
async updateUser(req: Request, res: Response, next: NextFunction) {
try {
const { id } = req.params;
const { name } = req.body;
const user = await this.userService.updateUser(id, { name });
return res.status(200).json({
id: user.id,
email: user.email,
name: user.name,
updatedAt: user.updatedAt,
});
} catch (error) {
next(error);
}
}
async deleteUser(req: Request, res: Response, next: NextFunction) {
try {
const { id } = req.params;
await this.userService.deleteUser(id);
return res.status(204).send();
} catch (error) {
next(error);
}
}
}Setting Up Test Server
API Tests with Supertest
Testing Authentication
JWT Authentication Middleware
OpenAPI/Swagger Validation
Contract Testing with Pact
Consumer Side (Order Service)
Provider Side (User Service)
Testing Rate Limiting
API Versioning Tests
Best Practices
1. Test HTTP Status Codes
2. Test Content-Type Headers
3. Test Error Responses
4. Test CORS Headers
Key Takeaways
What's Next?
Last updated