pub struct TestServer { /* private fields */ }Expand description
A real HTTP test server that routes requests through the full App pipeline.
Unlike TestClient which operates in-process without network I/O,
TestServer creates actual TCP connections and processes requests through
the complete HTTP parsing -> App.handle() -> response serialization pipeline.
This enables true end-to-end testing including:
- HTTP request parsing from raw bytes
- Full middleware stack execution
- Route matching and handler dispatch
- Response serialization to HTTP/1.1
- Cookie handling over the wire
- Keep-alive and connection management
§Architecture
Test Code TestServer (background thread)
| |
|-- TCP connect ----------------> |
|-- Send HTTP request ----------> |
| |-- Parse HTTP request
| |-- Create RequestContext
| |-- App.handle(ctx, req)
| |-- Serialize Response
|<-- Receive HTTP response ------ |
| |-- Log entry recorded§Example
use fastapi_core::testing::TestServer;
use fastapi_core::app::App;
use std::io::{Read, Write};
use std::net::TcpStream;
let app = App::builder()
.get("/health", |_, _| async { Response::ok().body_text("OK") })
.build();
let server = TestServer::start(app);
println!("Server running on {}", server.url());
// Connect with any HTTP client
let mut stream = TcpStream::connect(server.addr()).unwrap();
stream.write_all(b"GET /health HTTP/1.1\r\nHost: localhost\r\n\r\n").unwrap();
let mut buf = vec![0u8; 4096];
let n = stream.read(&mut buf).unwrap();
let response = String::from_utf8_lossy(&buf[..n]);
assert!(response.contains("200 OK"));
// Check server logs
let logs = server.log_entries();
assert_eq!(logs.len(), 1);
assert_eq!(logs[0].path, "/health");
assert_eq!(logs[0].status, 200);Implementations§
Source§impl TestServer
impl TestServer
Sourcepub fn start(app: App) -> Self
pub fn start(app: App) -> Self
Starts a new test server with the given App on a random available port.
The server begins listening immediately and runs in a background thread. It will process requests through the full App pipeline including all middleware, routing, and error handling.
§Panics
Panics if binding to a local port fails.
Sourcepub fn start_with_config(app: App, config: TestServerConfig) -> Self
pub fn start_with_config(app: App, config: TestServerConfig) -> Self
Starts a test server with custom configuration.
Sourcepub fn addr(&self) -> SocketAddr
pub fn addr(&self) -> SocketAddr
Returns the socket address the server is listening on.
Sourcepub fn log_entries(&self) -> Vec<TestServerLogEntry>
pub fn log_entries(&self) -> Vec<TestServerLogEntry>
Returns a snapshot of all log entries recorded so far.
Sourcepub fn request_count(&self) -> usize
pub fn request_count(&self) -> usize
Returns the number of requests processed.
Sourcepub fn clear_logs(&self)
pub fn clear_logs(&self)
Clears all recorded log entries.
Sourcepub fn shutdown_controller(&self) -> &ShutdownController
pub fn shutdown_controller(&self) -> &ShutdownController
Returns a reference to the server’s shutdown controller.
Use this to coordinate graceful shutdown in tests, including:
- Tracking in-flight requests via
crate::ShutdownController::track_request - Registering shutdown hooks via
crate::ShutdownController::register_hook - Checking shutdown phase via
crate::ShutdownController::phase
Sourcepub fn in_flight_count(&self) -> usize
pub fn in_flight_count(&self) -> usize
Returns the number of currently in-flight requests.
Sourcepub fn shutdown(&self)
pub fn shutdown(&self)
Signals the server to shut down gracefully.
This triggers the shutdown controller (which will cause the server to reject new requests with 503) and stops the accept loop. This is also called automatically on drop.
Sourcepub fn is_shutdown(&self) -> bool
pub fn is_shutdown(&self) -> bool
Returns true if the server has been signaled to shut down.