http-endpoint-server-harness
A Rust library for creating mock HTTP servers in your integration tests. Instead of mocking your HTTP client, spin up a real server that responds exactly as you configure it.
π― Why Use This?
When testing code that calls external HTTP APIs, you need to verify that:
- Your code sends the correct requests (right path, method, headers, body)
- Your code handles responses correctly (parsing, error handling, edge cases)
Traditional approaches have drawbacks:
| Approach | Problem |
|---|---|
| Mock the HTTP client | Doesn't test actual serialization, headers, or network code |
| Use a shared test server | Flaky tests, shared state issues, hard to customize per test |
| Record/replay (VCR) | Brittle when APIs change, hard to test error scenarios |
Server Harness gives you:
- β Real HTTP requests - Your code makes actual network calls
- β Isolated per test - Each test gets its own server with its own responses
- β Full control - Define exactly what each endpoint returns
- β Request inspection - Assert on the exact requests your code made
π¦ Use Cases
- Testing REST API clients - Verify your client library sends correct requests
- Integration testing - Test your app's behavior with specific API responses
- Error scenario testing - Simulate 500 errors, timeouts, malformed JSON
- Contract testing - Ensure your code handles the expected API format
- Webhook testing - Verify your code sends webhooks correctly
β¨ Features
- π Auto-shutdown - Server automatically shuts down when all handlers have been called
- β‘ Static & Dynamic Handlers - Predefined responses or compute responses based on the request
- π Request Collection - Capture all incoming requests for assertions
- π Sequential Handlers - Return different responses for successive calls
- π Axum Backend - Built on the battle-tested Axum web framework
Installation
[]
= "0.1"
= { = "1", = ["full"] }
= "0.12"
Quick Start
use *;
use SocketAddr;
use Duration;
async
Dynamic Handlers
Create handlers that respond dynamically based on the request:
let endpoint = new
.with_handler;
Sequential Handlers
Define multiple handlers for the same endpoint - each subsequent request uses the next handler:
let endpoint = new
.with_handler
.with_handler
.with_handler;
Custom Responses
// Custom status code
let handler = new;
// Custom headers
let handler = new;
π§ How It Works
βββββββββββββββββββ ββββββββββββββββββββ
β Your Code β GET /api/users β Mock Server β
β (HTTP Client) βββββββββββββββββββββΆβ (Axum-based) β
β β β β
β ββββββββββββββββββββββ Returns JSON β
β β 200 OK + JSON β you configured β
βββββββββββββββββββ ββββββββββββββββββββ
β
βΌ
Auto-shutdown when
all handlers consumed
β
βΌ
ββββββββββββββββββββ
β Collected Requestsβ
β for assertions β
ββββββββββββββββββββ
- Define endpoints - Specify path, method, and response for each endpoint
- Execute scenario - Server starts and waits for requests
- Your code runs - Makes real HTTP calls to the mock server
- Auto-shutdown - Server stops when all expected handlers have responded
- Assert - Verify collected requests match expectations
License
MIT - see LICENSE for details.