Testing (factories + route client)

defineFactory builds typed, seeded test data; testRoute(module) calls a route's loader/action with a synthesized request so you can assert on the result — no server, no DOM. The assertions below run live, with the same helpers you'd use in bun test.

Tip
For component testing (render + query + interact in a happy-dom DOM), use @bext-stack/framework/testing. testkit is pure (no DOM dependency) and targets app logic: data via factories, routes via testRoute.

Factory-generated data

u0user0@acme.coadmin
u1user1@acme.comember
u2user2@acme.coadmin

Live assertions

rejects an invalid signup (bad email + underage)pass
accepts a valid signup and coerces age to a numberpass
factory make() applies overrides (role = admin)pass
src/app/examples/testkit/page.tsxTSX
import { defineFactory, cycle, testRoute } from "@bext-stack/framework/testkit";
import * as signup from "../app/signup/page";  // your route module

const userFactory = defineFactory((n) => ({
  id: `u${n}`, email: `user${n}@example.com`, role: cycle("admin", "member")(n),
}));

test("rejects an invalid signup", async () => {
  const route = testRoute(signup);
  const res = await route.post({ email: "nope", age: "12" });  // calls the action
  expect(res.ok).toBe(false);
});

test("loader reads query params", async () => {
  expect(await testRoute(signup).get({ ref: "promo" })).toMatchObject({ ref: "promo" });
});