Askr documentation
Guides

Testing HTTP Applications

Testing HTTP Applications: a worked guide from route registry through to a production build.

Example

Start from an explicit route registry and add one application boundary at a time so browser, server, and production behavior stay testable.

export const registry = createRouteRegistry(() => {
  group({ layout: AppLayout }, () => {
    route('/', DashboardPage);
    route('/projects/{projectId}', ProjectPage);
    route('/404', NotFoundPage);
  });
});

Goal and architecture

`@askrjs/testing` drives an Askr server through its Web `Request`/`Response` boundary without opening a port. It's built on standard Web APIs (`Request`/`Response`/`Headers`/`URL`/`ReadableStream`/`AbortController`) with no Node-specific dependency inside the package itself, so "Node-only" describes how it's published and tested today, not a hard technical restriction baked into the implementation. It's runner-neutral and deliberately returns native `Response` objects so Vitest, Node test, or another assertion library can inspect the same contract production adapters receive.

Request injection

Use `inject(target, input, init?)` for one request, `createTestRequest()` when you need explicit query, JSON, form, header, or abort setup, and `createTestClient(target, options?)` for repeated method calls against one base URL. The target can be a fetch-compatible object or a request handler function; thrown errors and streaming bodies pass through unchanged.

Cookie handling is opt-in. Pass `cookies: true` for a client-private standards-backed jar, or share a jar created by `createTestCookieJar()` across clients. Redirects are manual by default; use `redirect: "follow"` to exercise cookie capture, relative locations, method rewriting, and cross-origin credential stripping without allowing the test to reach the network.

Verification

Assert the native response status, headers, and body, then cover abort propagation, redirect policy, and cookie scope when the endpoint uses them. Keep transport-adapter tests separate: request injection proves the application contract, while a smaller adapter suite proves Node or another host translates real network requests correctly.