Unit testen
Je hebt een functie geschreven. Ze werkt — tenminste, dat denk je. Maar wat gebeurt er als je hem volgende week aanpast? Of als een collega er iets aan verandert? Unit testen geven je de zekerheid dat een stuk code precies doet wat het moet doen, ook na elke toekomstige wijziging.
Wat is een unit test?
Een unit test is een geautomatiseerde controle van één geïsoleerde eenheid code — vaak een enkele functie. Je beschrijft wat je invoert, en wat je terugkrijgt. De testrunner voert alle tests uit en meldt direct welke slagen en welke falen.
Stel je hebt een functie die BTW berekent:
export function berekenBtw(bedrag, percentage) {
return bedrag * (percentage / 100)
}
Een unit test controleert dit automatisch:
import { berekenBtw } from './btw.js'
test('berekent 21% BTW over €100', () => {
expect(berekenBtw(100, 21)).toBe(21)
})
test('berekent 9% BTW over €50', () => {
expect(berekenBtw(50, 9)).toBe(4.5)
})
Als je later per ongeluk de formule aanpast, falen deze tests direct — vóórdat de fout in productie terechtkomt.
Vitest installeren
Voor dit project gebruiken we Vitest — een snelle, moderne testrunner die naadloos werkt met npm en TypeScript.
Heb je npm nog niet ingesteld? Lees eerst Package manager voor de installatie-instructies.
$ npm install --save-dev vitest
Voeg een testscript toe aan je package.json:
{
"scripts": {
"test": "vitest"
}
}
Je eerste test schrijven
Maak een bestand aan naast de code die je wilt testen. De conventie is: bestandsnaam.test.js of bestandsnaam.spec.js.
export function optellen(a, b) {
return a + b
}
import { describe, it, expect } from 'vitest'
import { optellen } from './optellen.js'
describe('optellen', () => {
it('telt twee positieve getallen op', () => {
expect(optellen(2, 3)).toBe(5)
})
it('telt een negatief getal op', () => {
expect(optellen(10, -4)).toBe(6)
})
it('telt twee nullen op', () => {
expect(optellen(0, 0)).toBe(0)
})
})
De drie bouwstenen
| Functie | Doel |
|---|---|
describe('naam', () => {}) | Groepeert gerelateerde tests onder één naam |
it('verwachting', () => {}) | Één individuele test — beschrijf wat er zou moeten gebeuren |
expect(waarde).toBe(verwacht) | De eigenlijke controle: is het resultaat wat we verwachten? |
Tests uitvoeren
$ npm test
Vitest draait in watch mode: hij bewaakt je bestanden en hervoert de tests automatisch zodra je iets opslaat. Zo krijg je direct feedback terwijl je werkt.
✓ optellen.test.js (3)
✓ telt twee positieve getallen op
✓ telt een negatief getal op
✓ twee nullen op
Test Files 1 passed (1)
Tests 3 passed (3)
Veelgebruikte matchers
Naast toBe heeft Vitest (gebaseerd op de Jest API) veel meer matchers:
// Exacte gelijkheid (primitieve waarden)
expect(1 + 1).toBe(2)
// Diepe gelijkheid (objecten en arrays)
expect({ naam: 'Anna' }).toEqual({ naam: 'Anna' })
// Controleren of een array een waarde bevat
expect([1, 2, 3]).toContain(2)
// Controleren of een functie een fout gooit
expect(() => deelDoor(10, 0)).toThrow('Deling door nul')
// Controleren op null of undefined
expect(resultaat).toBeNull()
expect(waarde).toBeDefined()
// Controleren of iets truthy of falsy is
expect(isIngelogd).toBeTruthy()
expect(isLeeg).toBeFalsy()
Wat moet je testen?
Richt je op puur logische functies: berekeningen, transformaties, validaties en hulpfuncties. Dit zijn de eenheden die het meeste baat hebben bij unit tests.
export function isGeldigEmail(email) {
return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email)
}
import { describe, it, expect } from 'vitest'
import { isGeldigEmail } from './validatie.js'
describe('isGeldigEmail', () => {
it('accepteert een geldig e-mailadres', () => {
expect(isGeldigEmail('jan@voorbeeld.nl')).toBe(true)
})
it('weigert een adres zonder @', () => {
expect(isGeldigEmail('janvoorbeeld.nl')).toBe(false)
})
it('weigert een leeg adres', () => {
expect(isGeldigEmail('')).toBe(false)
})
})
Tests schrijf je het beste samen met de code, niet achteraf. Zo dwing je jezelf na te denken over de verwachte invoer en uitvoer — wat leidt tot beter doordachte functies.
Unit tests zijn geen extra werk. Ze zijn de zekerheidsriem die je toestaat om met vertrouwen te refactoren, nieuwe functies toe te voegen en code door te geven aan anderen.