Skip to main content

kickjs-write-controller-test

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

Informations de source

Dépôt
forinda/kick-fullstack-netlify
Dernière activité de la source
18 septembre 2026 à 11:52
Langue détectée de SKILL.md
anglais
Étoiles
0
Forks
0

Options d'installation

Le prompt qui vérifie d'abord la source est sélectionné par défaut. Vous pouvez passer à une commande directe ou télécharger une copie locale.

Vérifiez les fichiers source

Lisez SKILL.md et les fichiers associés affichés par SkillsMP avant de décider de l'installer.

Affichage de SKILL.md

SKILL.md
Instructions source · Aperçu en lecture seule
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.
Voir sur GitHub