Docs
Mocks
Create mock HTTP servers and define mock routes for testing without real backends
Mocks
Create mock HTTP servers to test your application without depending on real backend services.
Overview
Mocks let you simulate API responses for testing. Define mock servers and routes with custom responses, delays, and sequences. Perfect for local development, CI/CD, and testing edge cases.
Basic Mock Setup
mockServer:
api-mock:
listen: ":8080"
mocks:
get-user:
server: api-mock
match:
method: GET
path: /users/{id}
respond:
- status: 200
body: '{"id": "123", "name": "John Doe"}'
Mock Servers
Define mock HTTP servers with mockServer.
Basic Server
mockServer:
api-mock:
listen: ":8080"
Server Configuration Fields
listen (required)
Listen address and port for the mock server.
Type: string
mockServer:
local-mock:
listen: ":8080" # Listen on all interfaces, port 8080
localhost-mock:
listen: "localhost:9000" # Listen on localhost only, port 9000
specific-ip:
listen: "0.0.0.0:3000" # Explicit IP address
basePath
Base path prefix for all routes on this server.
Type: string
mockServer:
api-mock:
listen: ":8080"
basePath: /api # All routes prefixed with /api
mocks:
get-users:
server: api-mock
match:
method: GET
path: /users # Full path: /api/users
respond:
- status: 200
tls
TLS/HTTPS configuration.
Type: object
mockServer:
https-mock:
listen: ":8443"
tls:
enabled: true
certFile: ./certs/localhost.crt
keyFile: ./certs/localhost.key
TLS fields:
enabled(boolean, required): Enable HTTPScertFile(string): Path to TLS certificatekeyFile(string): Path to TLS private key
defaults
Default response values for all routes on this server.
Type: object
mockServer:
api-mock:
listen: ":8080"
defaults:
status: 200
headers:
Content-Type: application/json
X-Mock-Server: quadrastack
Default fields:
status(integer): Default HTTP status codeheaders(object): Default response headersbody(string): Default response body
Mock Routes
Define mock routes with mocks.
Basic Route
mocks:
get-user:
server: api-mock
match:
method: GET
path: /users/{id}
respond:
- status: 200
body: '{"id": "123", "name": "John Doe"}'
Route Fields
server (required)
Name of the mock server this route belongs to.
Type: string
mocks:
get-user:
server: api-mock # References mockServer.api-mock
match (required)
Request matching rules.
Type: object
See Match Configuration below.
respond
Response sequence (same as sequence - use either one).
Type: array
mocks:
get-user:
server: api-mock
match:
method: GET
path: /users/{id}
respond:
- status: 200
body: '{"id": "123", "name": "John Doe"}'
sequence
Response sequence (same as respond - use either one). Responses are returned in order based on count.
Type: array
Note: Multiple responses in a sequence require Pro or Business license.
mocks:
flaky-endpoint:
server: api-mock
match:
method: POST
path: /orders
sequence:
- count: 2
status: 500
body: '{"error": "Internal server error"}'
- status: 201
body: '{"id": "order-123", "status": "created"}'
Match Configuration
Define how requests match routes.
Note: Advanced matching (query, headers, body, form, files) requires Pro or Business license. Free tier supports method and path matching only.
method (required)
HTTP method(s) to match.
Type: string or array of strings
mocks:
# Single method
get-user:
match:
method: GET
path: /users/{id}
# Multiple methods
user-endpoint:
match:
method: [GET, POST, PUT]
path: /users
path (required)
Path pattern to match. Use {paramName} for path parameters.
Type: string
mocks:
# Exact path
get-users:
match:
method: GET
path: /users
# Path parameter
get-user:
match:
method: GET
path: /users/{id}
# Multiple parameters
get-comment:
match:
method: GET
path: /posts/{postId}/comments/{commentId}
query
Query parameter assertions using assertion operators.
Type: object
mocks:
search-users:
match:
method: GET
path: /users
query:
page: exists
limit: "> 0"
filter: contains active
headers
Header assertions using assertion operators.
Type: object
mocks:
authenticated-endpoint:
match:
method: GET
path: /api/protected
headers:
Authorization: exists
Content-Type: contains application/json
body
JSONPath body assertions using assertion operators.
Type: object
mocks:
create-user:
match:
method: POST
path: /users
body:
$.name: "!empty"
$.email: 'matches ^[\w.]+@[\w.]+$'
$.age: ">= 18"
form
Form field assertions using assertion operators.
Type: object
mocks:
login:
match:
method: POST
path: /auth/login
form:
username: "!empty"
password: "length >= 8"
files
File field assertions using assertion operators.
Type: object
mocks:
upload:
match:
method: POST
path: /upload
files:
avatar: exists
document: "!empty"
Response Configuration
Define mock responses with status, headers, body, and delay.
status
HTTP status code for this response.
Type: integer
respond:
- status: 200
- status: 404
- status: 500
headers
Response headers.
Type: object
respond:
- status: 200
headers:
Content-Type: application/json
X-Request-ID: "123"
Cache-Control: "max-age=3600"
body
Response body (JSON, XML, plain text, etc.).
Type: string
respond:
# JSON
- status: 200
body: '{"id": "123", "name": "John Doe"}'
# XML
- status: 200
body: '<user><id>123</id><name>John Doe</name></user>'
# Plain text
- status: 200
body: 'OK'
Multi-line body:
respond:
- status: 200
body: |
{
"id": "123",
"name": "John Doe",
"email": "john@example.com",
"active": true
}
delay
Artificial delay before sending response.
Type: string (duration format)
Note: Response delays require Pro or Business license.
respond:
- status: 200
delay: "100ms" # Wait 100ms before responding
- status: 200
delay: "1s" # Wait 1 second
- status: 200
delay: "500ms" # Wait 500ms
count
Number of times to return this response before moving to the next in sequence.
Type: integer
Default: 0 (infinite)
sequence:
# Return 500 twice
- count: 2
status: 500
body: '{"error": "Service unavailable"}'
# Then return 200 forever
- status: 200
body: '{"status": "ok"}'
Complete Examples
Simple REST API Mock
mockServer:
api-mock:
listen: ":8080"
basePath: /api
defaults:
status: 200
headers:
Content-Type: application/json
mocks:
# GET /api/users
get-users:
server: api-mock
match:
method: GET
path: /users
respond:
- status: 200
body: |
[
{"id": "1", "name": "Alice"},
{"id": "2", "name": "Bob"}
]
# GET /api/users/{id}
get-user:
server: api-mock
match:
method: GET
path: /users/{id}
respond:
- status: 200
body: '{"id": "123", "name": "John Doe", "email": "john@example.com"}'
# POST /api/users
create-user:
server: api-mock
match:
method: POST
path: /users
body:
$.name: exists
$.email: exists
respond:
- status: 201
headers:
Location: /api/users/123
body: |
{
"id": "123",
"name": "New User",
"email": "new@example.com",
"createdAt": "2024-01-01T00:00:00Z"
}
# PUT /api/users/{id}
update-user:
server: api-mock
match:
method: PUT
path: /users/{id}
respond:
- status: 200
body: '{"id": "123", "name": "Updated User"}'
# DELETE /api/users/{id}
delete-user:
server: api-mock
match:
method: DELETE
path: /users/{id}
respond:
- status: 204
Flaky Service Simulation
mockServer:
flaky-api:
listen: ":8080"
mocks:
# Fail twice, then succeed
flaky-endpoint:
server: flaky-api
match:
method: POST
path: /process
sequence:
- count: 2
status: 503
delay: "100ms"
body: '{"error": "Service temporarily unavailable"}'
- status: 200
body: '{"status": "success", "result": "processed"}'
# Slow then fast
slow-endpoint:
server: flaky-api
match:
method: GET
path: /data
sequence:
- count: 1
status: 200
delay: "5s"
body: '{"slow": true}'
- status: 200
delay: "100ms"
body: '{"fast": true}'
Authentication Mock
mockServer:
auth-mock:
listen: ":9000"
mocks:
# Login - success
login-success:
server: auth-mock
match:
method: POST
path: /auth/login
body:
$.username: admin
$.password: exists
respond:
- status: 200
body: |
{
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"userId": "123",
"expiresIn": 3600
}
# Login - invalid credentials
login-failure:
server: auth-mock
match:
method: POST
path: /auth/login
body:
$.username: "!in [admin]"
respond:
- status: 401
body: '{"error": "Invalid credentials"}'
# Protected endpoint
protected-resource:
server: auth-mock
match:
method: GET
path: /api/protected
headers:
Authorization: exists
respond:
- status: 200
body: '{"data": "secret information"}'
# No auth
unauthorized:
server: auth-mock
match:
method: GET
path: /api/protected
headers:
Authorization: "!exists"
respond:
- status: 401
body: '{"error": "Unauthorized"}'
Rate Limiting Mock
mockServer:
rate-limited-api:
listen: ":8080"
mocks:
# First 5 requests succeed
rate-limit-ok:
server: rate-limited-api
match:
method: GET
path: /api/data
sequence:
- count: 5
status: 200
body: '{"data": "success"}'
- count: 3
status: 429
headers:
Retry-After: "60"
body: '{"error": "Rate limit exceeded"}'
- status: 200
body: '{"data": "success again"}'
Multi-Server Setup
mockServer:
# Main API server
api-mock:
listen: ":8080"
basePath: /api
defaults:
headers:
Content-Type: application/json
# Auth server
auth-mock:
listen: ":9000"
defaults:
headers:
Content-Type: application/json
# HTTPS mock
secure-mock:
listen: ":8443"
tls:
enabled: true
certFile: ./certs/localhost.crt
keyFile: ./certs/localhost.key
mocks:
# API route
get-users:
server: api-mock
match:
method: GET
path: /users
respond:
- status: 200
body: '[{"id": "1", "name": "Alice"}]'
# Auth route
login:
server: auth-mock
match:
method: POST
path: /login
respond:
- status: 200
body: '{"token": "abc123"}'
# Secure route
secure-data:
server: secure-mock
match:
method: GET
path: /secure/data
respond:
- status: 200
body: '{"secure": true}'
Using Mocks with Requests
Configure requests to use mock servers:
# Start mock server
mockServer:
api-mock:
listen: ":8080"
# Define mock routes
mocks:
get-users:
server: api-mock
match:
method: GET
path: /users
respond:
- status: 200
body: '[{"id": "1", "name": "Alice"}]'
# Configure HTTP client to use mock
httpClients:
default:
baseUrl: http://localhost:8080
# Make requests against mock
requests:
test-get-users:
method: GET
url: /users
expect:
status: 200
body:
$: type array
$.length: "> 0"
Running Mock Servers
Start Mock Server
# Start mock server(s) by name
quadrastack --mock-server api-mock
# Start multiple mock servers
quadrastack --mock-server api-mock --mock-server auth-mock
Mock Server Lifecycle
Mock servers run standalone with the --mock-server flag. When using this flag, the CLI starts the mock server(s) and waits for Ctrl+C to stop them. Tests are not executed when --mock-server is specified.
Best Practices
1. Use Realistic Response Bodies
respond:
- status: 200
body: |
{
"id": "123",
"name": "John Doe",
"email": "john@example.com",
"createdAt": "2024-01-01T00:00:00Z",
"updatedAt": "2024-01-01T00:00:00Z",
"active": true
}
2. Match on Important Fields Only
# Good - match on required fields
match:
method: POST
path: /users
body:
$.email: exists
$.name: exists
# Avoid - too specific, brittle
match:
method: POST
path: /users
body:
$.email: "exact@email.com"
$.name: "Exact Name"
$.age: 25
$.address: exists
3. Use Sequences for Complex Scenarios
sequence:
- count: 2
status: 500
body: '{"error": "Server error"}'
- status: 200
body: '{"status": "recovered"}'
4. Set Default Headers
mockServer:
api-mock:
listen: ":8080"
defaults:
status: 200
headers:
Content-Type: application/json
X-Mock-Server: quadrastack
5. Use basePath for API Versioning
mockServer:
api-v1:
listen: ":8080"
basePath: /api/v1
api-v2:
listen: ":8080"
basePath: /api/v2
6. Separate Servers by Concern
mockServer:
auth-mock:
listen: ":9000" # Authentication
api-mock:
listen: ":8080" # Main API
external-mock:
listen: ":7000" # Third-party API
7. Test Both Success and Failure
mocks:
# Success case
create-success:
server: api-mock
match:
method: POST
path: /users
body:
$.email: 'matches ^[\w.]+@[\w.]+$'
respond:
- status: 201
# Failure case
create-failure:
server: api-mock
match:
method: POST
path: /users
body:
$.email: "!matches ^[\\w.]+@[\\w.]+$"
respond:
- status: 400
body: '{"error": "Invalid email"}'
Assertion Operators
Use these operators in match sections:
exists- Field must exist!exists- Field must not exist!empty- Field must not be emptycontains text- String contains text!contains text- String does not contain textmatches regex- String matches regex> N- Number greater than>= N- Number greater or equal< N- Number less than<= N- Number less or equaltype <type>- Type check (string, number, array, object)in [val1, val2]- Value in list!in [val1, val2]- Value not in listlength N- Length equals Nlength > N- Length greater than N
See Assertions for complete reference.
See Also
- Assertions - Assertion operators reference
- HTTP Clients - Configuring client for mocks
- Requests - Testing against mocks
- CLI Reference - Mock server commands