Test and ship
Test handlers with requests
Exercise the Hono application directly with standard Request objects before adding network and database integration tests.
8 minute lesson
A Hono app exposes a fetch-compatible interface, so route tests can send requests without opening a TCP port.
Test observable status, headers, and body. Use a fresh application or injected repository per test so state cannot leak between cases. Avoid asserting private function calls when the HTTP result expresses the behavior better.
import test from 'node:test'
import assert from 'node:assert/strict'
import app from './app.js'
test('lists books', async () => {
const response = await app.request('/books')
assert.equal(response.status, 200)
assert.deepEqual(await response.json(), { books: [] })
})
These tests cover routing, middleware, validation, and serialization without the timing and port noise of a live server. They do not prove the Node adapter or real database works, which is why later tests add those boundaries. Keep each layer’s claim explicit.
Build a fresh app with an injected repository for every test. Assert externally visible behavior: status, media type, headers such as Location, and parsed body. Read a response body only once, just as a real Response stream requires. Add table-driven invalid inputs and verify that unexpected repository failures become a safe problem response rather than an unhandled rejection or leaked error.
Test list, create, invalid input, missing resource, and delete behavior with isolated state.
Lesson completed