Integration tests
Test the HTTP contract
Send real Request objects through the complete Hono routing and middleware stack and assert the public response contract.
8 minute lesson
Integration at the application boundary catches disagreements among routing, validation, domain logic, serialization, and error handling.
Create the app with injected dependencies, call its request interface, and assert status, headers, and parsed response. Include authentication and error middleware when those are part of the production stack.
test('creates a book through the public API', async () => {
const app = makeApp({ repository: new MemoryBooks() })
const response = await app.request('/books', {
method: 'POST',
headers: { 'content-type': 'application/json' },
body: JSON.stringify({ title: 'Dune', author: 'Frank Herbert' })
})
assert.equal(response.status, 201)
assert.match(response.headers.get('content-type'), /^application\/json/)
assert.deepEqual(await response.json(), {
id: 'book-1',
title: 'Dune',
author: 'Frank Herbert'
})
})
Sending a Request through the app proves more than calling the handler directly. It includes route matching, body parsing, middleware order, error translation, and serialization. A direct handler test can pass while production rejects the content type or an authentication middleware prevents the request.
Assert the public contract, not the implementation. Status, relevant headers, and response shape matter. A private repository method name does not. For error cases, assert a stable machine-readable code as well as the status; exact prose often changes without breaking clients.
Beware the opposite false positive: an in-memory repository cannot prove SQL, migration, or driver behavior. Keep this test focused on the application boundary and add repository integration tests for the storage boundary.
Test create then read, invalid JSON, unsupported content type, unknown route, and a storage exception. For each failure, write down which layer should produce the response and make sure the request actually crosses that layer.
Lesson completed