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

Take this course offline

Get every free book and course as PDF and EPUB files.

Get the download library →