Testing APIs
Tests are what let you change an API with confidence. Three layers, each catching a different class of bug, give good coverage without redundant effort.
The layers
Section titled “The layers”flowchart TD U[Unit: handlers, validation, pure logic - many, fast] --> I[Integration: real routes end-to-end - fewer] I --> C[Contract: responses match the OpenAPI spec - focused]
- Unit tests — exercise pure pieces: a validator, a pagination helper, an error mapper. Fast and numerous.
- Integration tests — send real requests through the actual router and assert status, headers, and body. These catch wiring bugs unit tests miss.
- Contract tests — assert that responses conform to the OpenAPI schema, so the implementation and the published contract never drift.
An integration-style assertion
Section titled “An integration-style assertion”Frameworks like Hono expose app.request(...), so you can call routes in-process without a network:
What to assert
Section titled “What to assert”For each endpoint, test the happy path and the failure paths: the right status code, the response shape, the error body for invalid input (does it match your problem+json?), auth required where expected, and pagination metadata on collections.
Common mistakes
Section titled “Common mistakes”Testing only the happy path Symptom:
- Tests only send valid requests — resource created, status 201
- Never test validation errors, auth failures, not-found, or conflicts
- Test every error path for every status code the API documents
Mocking the database in integration tests Symptom:
- Integration tests mock the database — the real query never runs
- Bad SQL or a broken constraint passes in tests but fails in production
- Use a real test database (in-memory SQLite or a test container)
💡 Real-world examples
Stripe:
- Test-mode API keys run tests against the real Stripe environment without moving real money
- Webhook testing via the Stripe CLI:
stripe listen --forward-to localhost:3000/webhookGitHub:
- No separate sandbox API — teams test against disposable test repos/orgs instead
- Contract tests against the published OpenAPI spec catch drift in CI before it ships
Sources: Stripe testing, Stripe CLI webhooks, GitHub REST API description