Vitest: teste unit
describe/test/expect, matcher-ele potrivite, mock-uri și fake timers.
Actualizat
Ce este Vitest
Vitest e un test runner: găsește fișierele de test (*.test.ts), le rulează și raportează ce a trecut și ce nu. E rapid, înțelege TypeScript și ESM fără configurare și are API-ul compatibil cu Jest (cel mai cunoscut runner).
npm i -D vitest
npx vitest # mod watch — rerulează la fiecare salvare
npx vitest run # o singură rulare (CI)Structura
// src/shared/lib/price.test.ts
import { describe, expect, test } from 'vitest'
import { applyDiscount } from './price'
describe('applyDiscount', () => {
test('WELCOME10 scade 10%', () => {
expect(applyDiscount(100, 'WELCOME10')).toBe(90)
})
test('cod necunoscut nu schimbă prețul', () => {
expect(applyDiscount(100, 'NOPE')).toBe(100)
})
})describegrupează teste înrudite.test(sauit) — un caz.expect(valoare).matcher(așteptat)— verificarea.
Pune testul lângă fișierul testat (colocation) — ușor de găsit, se mută împreună.
Matcher-ele — tipuri și când
| Matcher | Compară | Când |
|---|---|---|
toBe(x) |
identitate (Object.is) |
primitive: numere, stringuri, boolean |
toEqual(x) |
conținut, recursiv | obiecte și array-uri |
toStrictEqual(x) |
conținut + undefined-uri + clasă |
când contează exactitatea |
toBeTruthy() / toBeNull() / toBeUndefined() |
valori speciale | — |
toContain(x) |
element în array / substring | liste, texte |
toHaveLength(n) |
lungime | liste |
toThrow(msg?) |
funcția aruncă | validări |
resolves / rejects |
Promise | cod async |
expect({ a: 1 }).toBe({ a: 1 }) // ✗ obiecte diferite
expect({ a: 1 }).toEqual({ a: 1 }) // ✓ același conținut
expect(() => parseAge(-1)).toThrow('Vârstă invalidă')
await expect(loadUser(1)).resolves.toEqual({ id: 1 })Mock-uri
Un mock e o funcție falsă care înlocuiește o dependență (API, timp, random) ca testul să fie rapid și determinist.
import { vi } from 'vitest'
const onSave = vi.fn() // funcție spion
render(<Form onSave={onSave} />)
// ... userul trimite formularul
expect(onSave).toHaveBeenCalledWith({ email: 'a@x.ro' })
vi.useFakeTimers() // controlezi timpul
vi.advanceTimersByTime(300) // ex. pentru debounce| Tip | Ce face |
|---|---|
vi.fn() |
funcție care înregistrează apelurile |
vi.spyOn(obj, 'method') |
spionează o metodă existentă |
vi.mock('./api') |
înlocuiește un modul întreg |
vi.useFakeTimers() |
timp controlat |
Nu exagera cu mock-urile: cu cât mock-uiești mai mult, cu atât testezi mai puțin din realitate. Pentru request-uri HTTP, MSW interceptează la nivel de rețea — codul rămâne neatins.
Setup cu Next.js
Next are un ghid oficial pentru Vitest (cu @vitejs/plugin-react și jsdom pentru componente). Atenție: Server Components async nu se testează încă bine unit — pentru ele, folosește E2E.
Pe scurt
- Vitest rulează
*.test.ts;describe/test/expect. toBepentru primitive,toEqualpentru obiecte.vi.fnși fake timers pentru dependențe; mock-uiește cât mai puțin.