Orientation Arc
Routing Algorithms
Rendering and JSX
Runtime Adapters
Middleware Ecosystem
Developer Helpers
System Utilities
The following files were used as context for generating this wiki page:
Testing utilities in Hono are designed to bridge the gap between development and production environments, providing a seamless way to simulate network requests and verify application behavior without needing to spin up an actual HTTP server. By leveraging the Web Standards-compliant nature of Hono, these utilities allow developers to pass a Request or a URL string directly into an application instance, returning a standard Response object. This approach ensures that tests are fast, isolated, and reflect the exact logic execution path that a real production request would follow.
The core of this system is centered on the request method exposed by the Hono class. This method abstracts the complexities of request creation and dispatching, handling the conversion of simplified inputs (like path strings) into full-fledged Request objects. By integrating deeply with the framework's routing and dispatch mechanisms, these utilities allow for full-stack integration testing, ensuring that middleware, route matching, and error handling all perform as expected during development.
request Method MechanismThe request utility serves as the primary gateway for unit and integration testing. Its mechanism transforms simple input parameters into a fully qualified Request object and dispatches it to the application's internal #dispatch flow.
string or URL, the method ensures it is rooted correctly using mergePath and defaults to a http://localhost origin if no host is specified.Request object using the normalized URL and provided RequestInit parameters.fetch method, which is the internal entry point that performs route matching, middleware composition, and final response execution.// Testing an endpoint:
test('GET /hello is ok', async () => {
const res = await app.request('/hello')
expect(res.status).toBe(200)
})Sources: src/hono-base.ts:499-517
The execution flow for an app.request() call eventually reaches #dispatch inside src/hono-base.ts. This is the core logic engine of the framework.
router to match the incoming method and path (derived via getPath).Context object is instantiated, encapsulating the Request, the router's matchResult, and optional environment bindings (env) or execution contexts.compose utility to execute the middleware chain. This involves iterating through the handlers matched by the router and managing the next() calls.Context object remains in a non-finalized state, an error is thrown. This forces developers to ensure that every path results in a Response being returned.Important
A Context must be finalized before the dispatch cycle concludes. If a Response is not explicitly set or returned, the system treats it as an error-prone state, preventing silent failures.
Sources: src/hono-base.ts:406-466
Hono's testing utilities account for the serverless environments the framework targets (e.g., Cloudflare Workers). The #dispatch method accepts an executionCtx, which provides mock implementations for methods like waitUntil and passThroughOnException.
When running in environments like Vitest or Deno, the request method behaves exactly as it would in production by providing a standard environment object that conforms to the ExecutionContext interface. This allows testing middleware that interacts with async background tasks (using c.executionCtx.waitUntil) without breaking the test runner.
Sources: src/context.ts:31-52, src/hono-base.ts:407-408
The testing utilities inherit the global error handling configuration of the Hono application instance. If an error is caught during the dispatch process—whether from a handler throwing an exception or an unfinalized context—the errorHandler is invoked.
The error handler itself is designed to handle HTTPResponseError specifically. If an error contains a getResponse method, the test will correctly capture the intended response object rather than a generic "Internal Server Error." This is vital for testing custom API error formats or authentication failures.
const errorHandler: ErrorHandler = (err, c) => {
if ('getResponse' in err) {
const res = err.getResponse()
return c.newResponse(res.body, res)
}
console.error(err)
return c.text('Internal Server Error', 500)
}Sources: src/hono-base.ts:35-42
Beyond server-side testing, Hono provides hc (Hono Client) for type-safe interaction. Testing the client involves creating a proxy that can be called with specific API paths. This utility uses createProxy internally to build path hierarchies.
When testing the client, you can pass a custom fetch implementation into the ClientRequestOptions. This is an essential pattern for testing the client against mock services (like MSW - Mock Service Worker). By supplying opt.fetch, you can redirect all client calls to a sandboxed fetch environment.
// Passing a custom fetch for MSW/Node-fetch testing
const res = await hc('/api', { fetch: myMockFetch }).user.$get()Sources: src/client/client.ts:133-224
Sources: src/hono-base.ts:499-517
This example shows how to perform a full integration test on an app instance, exercising route matching, context modification, and final response validation.
import { Hono } from './hono'
const app = new Hono()
app.use('*', async (c, next) => {
c.set('user', 'admin')
await next()
})
app.get('/hello', (c) => {
return c.json({ user: c.get('user') })
})
// Integration Test
test('GET /hello works and reflects middleware state', async () => {
const res = await app.request('/hello')
const data = await res.json()
expect(res.status).toBe(200)
expect(data.user).toBe('admin')
})Sources: src/hono-base.ts:499-517, src/context.ts:546-556