Tests
Vitest, mocks Prisma, lancement et ajout de tests.
Le boilerplate utilise Vitest en environnement Node, sans framework de
test E2E. Les tests vivent à côté du code testé : lib/foo.ts →
lib/foo.test.ts.
Setup
vitest.config.ts :
import { defineConfig } from "vitest/config";
import path from "node:path";
export default defineConfig({
test: {
environment: "node",
include: ["lib/**/*.test.ts", "tests/**/*.test.ts"],
globals: false,
},
resolve: {
alias: { "@": path.resolve(__dirname, ".") },
},
});globals: false → tu importes explicitement describe, it, expect,
vi depuis vitest. Plus verbeux, mais plus clair.
Lancement
npm run test # une fois
npm run test:watch # mode watchTests existants
| Fichier | Couvre |
|---|---|
lib/auth-lockout.test.ts | Progression lockout, decay 24h, clear |
lib/two-factor.test.ts | Génération + verify code 6 chiffres |
lib/referral.test.ts | Génération code unique, alphabet sans ambiguïté |
lib/site-config.test.ts | pickLocalized fallbacks |
lib/url.test.ts | getAppUrl avec headers / fallback AUTH_URL |
lib/username.test.ts | Validation username, génération |
Tous purement unitaires — pas de DB réelle ni d'appels réseau.
Mocker Prisma
Pattern utilisé dans two-factor.test.ts :
import { describe, it, expect, vi, beforeEach } from "vitest";
const findUnique = vi.fn();
const create = vi.fn();
const deleteMany = vi.fn();
vi.mock("./prisma", () => ({
prisma: {
verificationToken: {
findUnique: (args: unknown) => findUnique(args),
create: (args: unknown) => create(args),
deleteMany: (args: unknown) => deleteMany(args),
},
},
}));
import { issueTwoFactorCode } from "./two-factor";
beforeEach(() => {
findUnique.mockReset();
create.mockReset();
deleteMany.mockReset();
create.mockResolvedValue({});
deleteMany.mockResolvedValue({});
});
describe("issueTwoFactorCode", () => {
it("creates a 6-digit code", async () => {
const code = await issueTwoFactorCode("foo@bar.com");
expect(code).toMatch(/^\d{6}$/);
expect(create).toHaveBeenCalledOnce();
});
});Important : vi.mock() doit être avant l'import du module testé,
sinon Prisma est résolu pour de vrai.
Ajouter un test
- Crée
lib/myfeature.test.ts(suffixe.test.tsobligatoire pour matcher). - Importe les helpers Vitest (pas de globals).
- Si ton code touche à Prisma → mock comme ci-dessus.
- Si ton code touche à
next/headers,next-intl, ou une autre API Next.js → mock-le aussi (le runtime Node de Vitest ne les fournit pas).
Tests d'intégration ?
Le boilerplate n'inclut pas de setup E2E (Playwright/Cypress) volontairement
— ça dépend trop de ton domaine métier. Si tu en ajoutes, mets-les dans
tests/e2e/ et étends vitest.config.ts pour les exclure du run unitaire.
Allez plus loin
- Architecture — co-localisation lib + test
- Lockout — exemple de logique testée
- 2FA — exemple de logique testée