Getting started¶
This page shows how to install localstub and write your first test: stub a JSON response, make a request with a real HTTP client, and assert on the request the server recorded. You need Python 3.12 or newer.
Installation¶
or with pip:
The example below uses httpx as the client, but any HTTP client works. In your own tests, point the client you are testing at the stub.
Your first test¶
Save this as example.py:
import asyncio
import httpx
from localstub import AsyncHTTPTestServer
async def main() -> None:
async with AsyncHTTPTestServer() as server:
# Configure the response the server returns.
server.set_json_response({"status": "ok"})
# Point a real HTTP client at the server.
async with httpx.AsyncClient() as client:
response = await client.get(f"{server.url}status")
assert response.status_code == 200
assert response.json() == {"status": "ok"}
# The server recorded the request the client sent.
request = server.last_request
assert request is not None
assert request.method == "GET"
assert request.target == "/status"
assert request.headers["host"] is not None
asyncio.run(main())
Run the example¶
The example uses httpx, which is not installed with localstub. Use
uv to provide it for this command:
How it works¶
AsyncHTTPTestServer()started a real asyncio HTTP server on a random local port. Its base URL isserver.url, and theasync withblock shuts the server down on exit.server.set_json_response({"status": "ok"})configured a static response: every request receives HTTP 200 with a JSON body andContent-Type: application/json.- The
httpxclient made a real HTTP request over a real socket. Nothing was mocked or patched. - The server recorded the request.
server.last_requestholds the most recent one andserver.requestsholds all of them, so you can assert on the method, target, headers, and body your client sent.
Next steps¶
This example used plain HTTP against server.url. From here you can:
- Configure richer responses: error statuses, response sequences for retry testing, and dynamic handlers.
- Test an unmodified client over HTTPS with the TLS intercept proxy (see the example on the landing page).
- Inspect the raw wire bytes of each request, including chunked
framing and trailers, via
request.wire_raw_bytes.