Skip to content

Testing Utilities

createTestApp() — Alles in einem Aufruf

const app = await createTestApp({
features: [orderFeature, clientFeature],
});
afterAll(() => app.cleanup());

Erstellt: echte PostgreSQL (frische DB), echte Redis (eigener DB-Index), Feature Registry, Pipeline — alles real, keine Mocks.

Testen ohne HTTP

// Write direkt aufrufen:
const result = await app.write("order.create", {
payload: { clientId: 1, state: "new" },
as: { userId: 1, tenantId: 1, roles: ["Admin"] },
});
expect(result.isSuccess).toBe(true);
// Query direkt aufrufen:
const orders = await app.query("order.list", {
payload: { limit: 50 },
as: { userId: 1, tenantId: 1, roles: ["Admin"] },
});
expect(orders.items).toHaveLength(1);

Entity Factories

Auto-generiert aus Schema. Nur angeben was fuer den Test relevant ist — Rest wird mit sinnvollen Defaults gefuellt.

// Manuell (ohne Factory — muehsam):
await db.insert(orders).values({
tenantId: 1, clientId: 1, state: "new", priority: 0,
currency: "EUR", insertedById: 1, insertedAt: new Date(),
isDeleted: false, version: 1,
});
// Mit Factory — nur was relevant ist:
const order = await app.create("order", { clientId: 1 });
// state=new, priority=0, currency=EUR, tenantId aus Context, etc.
// Mehrere auf einmal:
const orders = await app.createMany("order", { clientId: 1 }, { count: 50 });

Wie Defaults funktionieren

Feld-TypFactory-Default
text (required)"test_{fieldName}_{counter}"
text (optional)null
numberdefault aus Schema oder 0
booleandefault aus Schema oder false
selectErste Option
datenew Date()
Relations (foreignKey)Muss angegeben werden oder auto-create

Auto-Create Relations

// Order braucht Client — Factory erstellt automatisch einen:
const order = await app.create("order");
// → Client wird automatisch erstellt, clientId gesetzt
// Oder explizit:
const client = await app.create("client", { name: "ACME" });
const order = await app.create("order", { clientId: client.id });

Test-Helpers

// User simulieren:
const admin = app.asUser({ id: 1, tenantId: 1, roles: ["Admin"] });
const driver = app.asUser({ id: 2, tenantId: 1, roles: ["Driver"] });
// Access testen:
await expect(app.write("order.create", { payload, as: driver }))
.rejects.toThrow(AccessDeniedError);
// Events pruefen:
const events = app.getEmittedEvents();
expect(events).toContainEqual({ type: "orders.order.created", payload: { ... } });
// Jobs pruefen:
const jobs = app.getEnqueuedJobs();
expect(jobs).toContainEqual({ name: "orders.sendNotification", payload: { ... } });

Full-Stack Integration Test

// Mit HTTP (Hono Test Client):
const response = await app.client.write.$post({
json: { type: "order.create", payload: { clientId: 1 }, requestId: "test-1" },
}, { headers: admin.authHeader() });
expect(response.status).toBe(200);
expect((await response.json()).isSuccess).toBe(true);