Writing a Contract Test Suite for Your Own LLM Gateway
Learn how to effectively test your LLM proxy gateway using local fake providers to catch header hygiene issues, error mapping bugs, and streaming timing flaws.

Stock photo for illustration only, not from the actual event
- The most interesting proxy failures happen in your layer, not inside the model.
- Use a local fake provider instead of a real model to run tests fast and deterministically.
- Ensure unknown fields survive serialization to prevent silent data drops.
- Validate both byte content and timing constraints for streaming responses.
If you run a proxy in front of one or more model providers, the interesting failures are not in the model. They are in your layer: a header you forwarded that you should have stripped, an upstream 429 you turned into a 500, or a stream you accidentally buffered.
A gateway sits between your applications and providers, promising to speak the OpenAI-compatible contract downstream while translating faithfully upstream. Almost every bug that costs you an incident lives in one of those two promises rather than in the inference itself.

Stock photo for illustration only, not from the actual event
That means the suite you want is not the one from evaluating a candidate provider. You need a suite that checks whether your code preserves shape without touching a provider at all: fast, deterministic, and on every pull request. A suite that needs a real model runs nightly at best, and a proxy bug found nightly has already shipped.
Building a dedicated contract test suite for an LLM gateway is a vital engineering practice. As AI providers frequently update their schemas and add new metadata fields, robust proxy testing ensures that downstream applications do not break due to unhandled response changes or dropped parameters.
The single most valuable assertion in a gateway suite is that unknown fields survive. A gateway that parses an upstream response into a typed struct and re-serialises it will silently drop every field its struct does not know about — and providers add fields constantly. Your users lose logprobs, a reasoning block, or a cache-hit count without noticing until a ticket is opened.
Error mapping is another critical contract that teams write once and never test. Assert each upstream status your gateway receives against the downstream status it produces: a 429 must stay a 429 so clients' backoff engages, and a Retry-After header must survive since it carries the only number worth obeying.
Source: Dev.to
Found something wrong in this article? Report an issue with this article
Comments
Leave a Comment