Lightweight, per-test HTTP mock server for testing API integrations
cargo add philiprehberger-mock-serverLightweight, per-test HTTP mock server for testing API integrations
[dependencies]
philiprehberger-mock-server = "0.2.0"
use philiprehberger_mock_server::{MockServer, Method};
#[tokio::test]
async fn test_api_call() {
let server = MockServer::start().await;
server
.mock(Method::GET, "/users")
.with_status(200)
.with_body(r#"[{"id": 1, "name": "Alice"}]"#)
.with_header("Content-Type", "application/json")
.create();
// Use server.url() as the base URL for your HTTP client
let base_url = server.url(); // e.g. http://127.0.0.1:54321
}
use philiprehberger_mock_server::{MockServer, Method};
use serde_json::json;
#[tokio::test]
async fn test_json_response() {
let server = MockServer::start().await;
server
.mock(Method::POST, "/api/data")
.with_status(201)
.with_json(json!({"status": "created", "id": 42}))
.create();
}
use philiprehberger_mock_server::{MockServer, Method};
use std::time::Duration;
#[tokio::test]
async fn test_timeout_handling() {
let server = MockServer::start().await;
server
.mock(Method::GET, "/slow")
.with_status(200)
.with_body("finally")
.with_delay(Duration::from_millis(500))
.create();
}
use philiprehberger_mock_server::{MockServer, Method};
#[tokio::test]
async fn test_request_recording() {
let server = MockServer::start().await;
server
.mock(Method::POST, "/webhook")
.with_status(200)
.create();
// ... make requests to server.url() ...
let requests = server.requests();
assert_eq!(requests.len(), 1);
assert_eq!(requests[0].method, "POST");
assert_eq!(requests[0].path, "/webhook");
}
use philiprehberger_mock_server::{MockServer, Method};
#[tokio::test]
async fn test_role_routing() {
let server = MockServer::start().await;
server
.mock(Method::GET, "/who")
.with_status(200)
.with_body("admin")
.match_header("X-Role", "admin")
.create();
server
.mock(Method::GET, "/who")
.with_status(200)
.with_body("user")
.match_header("X-Role", "user")
.create();
}
use philiprehberger_mock_server::{MockServer, Method};
#[tokio::test]
async fn test_event_dispatch() {
let server = MockServer::start().await;
server
.mock(Method::POST, "/webhook")
.with_status(200)
.with_body("event-a")
.match_body(r#"{"event":"a"}"#)
.create();
}
use philiprehberger_mock_server::{MockServer, Method};
#[tokio::test]
async fn test_search_lang() {
let server = MockServer::start().await;
server
.mock(Method::GET, "/search")
.with_status(200)
.with_body("rust")
.match_query("lang", "rust")
.create();
}
| Item | Description |
|---|---|
MockServer::start() | Start a mock server on a random port |
.url() | Base URL of the running server |
.mock(method, path) | Begin building a mock definition |
.requests() | Get all recorded requests |
.reset() | Clear all mocks and recorded requests |
MockBuilder::with_status(code) | Set response status code |
MockBuilder::with_body(body) | Set response body |
MockBuilder::with_json(value) | Set JSON response body and content type |
MockBuilder::with_header(key, value) | Add a response header |
MockBuilder::with_delay(duration) | Add a delay before responding |
MockBuilder::expect(times) | Expect exactly N calls (verified on drop) |
MockBuilder::match_header(name, value) | Require a matching request header (case-insensitive name) |
MockBuilder::match_body(body) | Require an exact request body |
MockBuilder::match_query(key, value) | Require a query parameter to be present with this value |
MockBuilder::create() | Register the mock on the server |
Method | HTTP method enum: GET, POST, PUT, DELETE, PATCH, HEAD, OPTIONS |
RecordedRequest | Captured request with method, path, headers, body, query |
cargo test
cargo clippy -- -D warnings
If you find this project useful: