24 / 89 · 04 API & Contract Testing with AI · AI-Enhanced Contract Generation and Maintenance← prev⊞ allnext →☰ Read as one page
4.4Contract Testing Anti-Patterns
Anti-Pattern 1: Exact Value Matching
// BAD: contracts that match exact values
.willRespondWith(200, (builder) => {
builder.jsonBody({
id: "550e8400-e29b-41d4-a716-446655440000", // Exact ID
name: "Blue Widget", // Exact name
price: 29.99, // Exact price
});
})
// GOOD: contracts that match structure and type
.willRespondWith(200, (builder) => {
builder.jsonBody({
id: uuid(), // Any valid UUID
name: like("Blue Widget"), // Any string
price: decimal(29.99), // Any decimal number
});
})
Anti-Pattern 2: Testing Provider Logic in Consumer Tests
// BAD: consumer test that validates provider business logic
.executeTest(async (mockServer) => {
const product = await client.getProduct('ABC-123');
expect(product.price).toBeLessThan(100); // Business rule validation
expect(product.name.length).toBeLessThan(200); // Schema constraint
})
// GOOD: consumer test that validates consumer behavior
.executeTest(async (mockServer) => {
const product = await client.getProduct('ABC-123');
expect(product.name).toBeDefined(); // Consumer needs the name field
expect(product.price).toBeDefined(); // Consumer needs the price field
})
Anti-Pattern 3: One Massive Contract
// BAD: one test with every field
.willRespondWith(200, builder => {
builder.jsonBody({
id: uuid(), name: like(""), price: decimal(0),
category: like(""), in_stock: like(true),
created_at: like(""), updated_at: like(""),
description: like(""), images: eachLike(""),
tags: eachLike(""), weight: decimal(0),
dimensions: like({}), shipping_info: like({}),
// ... 30 more fields
});
})
// GOOD: one test per consumer use case, only fields the consumer uses
// Use case 1: product listing (needs id, name, price, image)
// Use case 2: product detail (needs all fields)
// Use case 3: cart display (needs id, name, price, in_stock)