Skip to main content

kickjs-write-controller-test

Use when adding a Vitest test that exercises an HTTP route or DI graph.

Quellinformationen

Repository
forinda/kick-fullstack-netlify
Letzte Quellaktivität
18. September 2026 um 11:52
Erkannte Sprache von SKILL.md
Englisch
Sterne
0
Forks
0

Installationsoptionen

Standardmäßig ist der Prompt ausgewählt, der zuerst die Quelle prüft. Sie können zu einem direkten Befehl wechseln oder eine lokale Kopie herunterladen.

Quelldateien prüfen

Lesen Sie SKILL.md und alle von SkillsMP angezeigten Begleitdateien, bevor Sie sich für eine Installation entscheiden.

SKILL.md wird angezeigt

SKILL.md
Quellanweisungen · Schreibgeschützte Vorschau
name
kickjs-write-controller-test
description
Use when adding a Vitest test that exercises an HTTP route or DI graph.
<!-- Generated by `kick g agents` for kick-fullstack-server. Edits are overwritten on the next refresh; keep customisation in a SKILL.local.md alongside. --> **Template** (copy/paste, adjust): ```ts import { describe, it, expect, beforeEach } from 'vitest' import request from 'supertest' import { Container } from '@forinda/kickjs' import { createTestApp } from '@forinda/kickjs-testing' // Side-effect import — registers the env schema, exactly as src/index.ts does. // `createTestApp` never loads the entry file, so without this // `ConfigService.get('YOUR_KEY')` is undefined under test while `@Value()` // still appears to work via its process.env fallback — the two disagree only // in tests. import '@/config' describe('UserController', () => { beforeEach(() => Container.reset()) // isolate DI between tests it('returns users', async () => { // `createTestApp` takes an OPTIONS OBJECT and returns // `{ app, container }`. Passing a bare array throws // "this.options.modules is not iterable"; the result has no `.get()`. // // Drive `app.handle` rather than `expressApp`: it is the Application's // own Node listener, so the test runs on whichever runtime the app is // configured with. Pass `runtime` to `createTestApp` to match production. const { app } = await createTestApp({ // Matches this project's `modules.style`. modules: [UserModule()], }) const res = await request(app.handle.bind(app)).get('/api/v1/users') expect(res.status).toBe(200) }) }) ``` **Typed handler signature** — pair with `kick typegen` so `ctx.body` / `params` / `query` are typed by the route's Zod schema: ```ts @Post('/', { body: createTodoSchema }) async create(ctx: Ctx<KickRoutes.TodoController['create']>) { // ctx.body is typed from createTodoSchema; ctx.params from the route. // Returning (vs ctx.created) lets typegen infer the response type. return reply(201, await this.service.create(ctx.body)) } ``` **Red flags**: - `new Container()` — wrong; use `Container.reset()` in `beforeEach` or `Container.create()` for fully isolated graphs. - `Container.getInstance().reset()` — wrong; same fix. - Sharing a container instance across `it()` blocks — leaks registrations between tests. - Injecting a `Scope.REQUEST` service into a `SINGLETON` — container throws at resolve. Singletons must resolve request-scoped services explicitly per call. - Calling `getRequestValue<string>('traceId')` — the generic slot is the **key** type, not the value type; widens key and bypasses typed lookup. - Asserting on `res.body.requestId` when `requestId()` middleware isn't mounted in the test app — value will be `undefined`. - Using `Scope.REQUEST` services in a test without mounting `requestScopeMiddleware()` — `getRequestValue` silently returns `undefined`; `getRequestStore` throws. **Nuances**: - `@Inject` and `@Autowired` are interchangeable — same runtime, same types; pick by readability. - `@Value('MISSING_KEY')` with no default **throws on property access**, not at construction — tests that exercise the getter will surface the missing-env issue.
Auf GitHub ansehen