Expectations
Master the art of defining what your MCP server should return with flexible and powerful expectation patterns.
Expectation Types
MCP Jest offers several ways to validate server responses, from exact matches to flexible pattern matching.
Exact Match
The most precise way to validate responses - every field must match exactly:
{
"name": "Should return exact greeting",
"type": "tool",
"tool": "greet",
"arguments": { "name": "Alice" },
"expect": {
"content": [
{
"type": "text",
"text": "Hello, Alice! Welcome to our service."
}
]
}
}
Type Matching
Validate the structure and types without checking exact values:
{
"name": "Should return weather data with correct types",
"type": "tool",
"tool": "get-weather",
"arguments": { "city": "London" },
"expect": {
"temperature": { "type": "number" },
"description": { "type": "string" },
"humidity": { "type": "number" },
"timestamp": { "type": "string" },
"coords": {
"lat": { "type": "number" },
"lon": { "type": "number" }
}
}
}
Pattern Matching
Use regular expressions to match dynamic content:
{
"name": "Should return properly formatted timestamp",
"type": "tool",
"tool": "current-time",
"expect": {
"timestamp": {
"pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}Z$"
},
"readable": {
"pattern": "^(Monday|Tuesday|Wednesday|Thursday|Friday|Saturday|Sunday)"
}
}
}
Range Validation
Validate numeric ranges and constraints:
{
"name": "Should return valid temperature reading",
"type": "tool",
"tool": "temperature-sensor",
"expect": {
"celsius": {
"type": "number",
"min": -50,
"max": 60
},
"fahrenheit": {
"type": "number",
"min": -58,
"max": 140
}
}
}
Array Validation
Validate arrays with length constraints and item patterns:
{
"name": "Should return list of users",
"type": "tool",
"tool": "list-users",
"expect": {
"users": {
"type": "array",
"minLength": 1,
"maxLength": 10,
"items": {
"id": { "type": "string" },
"name": { "type": "string" },
"email": {
"pattern": "^[\\w.-]+@[\\w.-]+\\.[a-zA-Z]{2,}$"
}
}
}
}
}
Partial Matching
Sometimes you only care about specific fields. Use partial matching to ignore irrelevant data:
{
"name": "Should include essential user data",
"type": "tool",
"tool": "get-user",
"arguments": { "id": "123" },
"expect": {
"user": {
"id": "123",
"name": { "type": "string" },
"status": "active"
// Other fields like lastLogin, preferences, etc. are ignored
}
}
}
Error Expectations
Test that your server handles errors gracefully:
{
"name": "Should handle invalid user ID",
"type": "tool",
"tool": "get-user",
"arguments": { "id": "nonexistent" },
"expectError": true,
"expect": {
"error": {
"code": -32602,
"message": {
"pattern": ".*not found.*"
}
}
}
}
Common Error Patterns
Validation Errors
{
"name": "Should reject invalid email",
"type": "tool",
"tool": "create-user",
"arguments": { "email": "invalid-email" },
"expectError": true,
"expect": {
"error": {
"code": -32602,
"message": "Invalid email format"
}
}
}
Authorization Errors
{
"name": "Should require authentication",
"type": "tool",
"tool": "delete-user",
"arguments": { "id": "123" },
"expectError": true,
"expect": {
"error": {
"code": -32600,
"message": {
"pattern": ".*(unauthorized|forbidden).*"
}
}
}
}
Advanced Matching
Conditional Expectations
Different expectations based on conditions:
{
"name": "Should return appropriate greeting",
"type": "tool",
"tool": "time-based-greeting",
"arguments": {},
"expect": {
"oneOf": [
{
"greeting": "Good morning",
"time": { "pattern": "^(0[6-9]|1[01]):" }
},
{
"greeting": "Good afternoon",
"time": { "pattern": "^1[2-7]:" }
},
{
"greeting": "Good evening",
"time": { "pattern": "^(1[89]|2[0-3]):" }
}
]
}
}
Custom Validators
For complex validation logic, use custom validators:
{
"name": "Should return valid JSON",
"type": "resource",
"resource": "file://config.json",
"expect": {
"contents": [
{
"text": {
"validator": "json",
"schema": {
"type": "object",
"properties": {
"version": { "type": "string" },
"features": {
"type": "array",
"items": { "type": "string" }
}
},
"required": ["version"]
}
}
}
]
}
}
Performance Expectations
Validate not just responses, but also performance characteristics:
{
"name": "Should respond quickly",
"type": "tool",
"tool": "quick-operation",
"arguments": {},
"expect": {
"result": { "type": "string" }
},
"performance": {
"maxDuration": 100, // Should complete within 100ms
"maxMemory": "10MB" // Should use less than 10MB RAM
}
}
Debugging Failed Expectations
When expectations fail, MCP Jest provides detailed diff output:
✗ Should return user profile (156ms)
Expected response to match:
{
"user": {
"name": "John Doe",
"age": 30,
"status": "active"
}
}
Received:
{
"user": {
"name": "John Doe",
"age": 31,
"status": "active",
"lastLogin": "2024-01-15T10:30:00Z"
}
}
Differences:
user.age: expected 30, got 31
user.lastLogin: unexpected field
Best Practices
✅ Good Practices
- • Use type matching for dynamic data like timestamps
- • Test both success and error scenarios
- • Use partial matching to focus on what matters
- • Validate structure before validating content
- • Use meaningful test names that describe expectations
❌ Avoid
- • Over-specifying expectations for dynamic data
- • Ignoring error handling in tests
- • Using exact matches for timestamps or IDs
- • Making tests brittle with unnecessary constraints
- • Testing implementation details instead of behavior
🎯 Master Expectations
With powerful expectation patterns, you can write tests that are both precise and maintainable.
Learn About Snapshot Testing →