Testing mit Vitest in JavaScript
Testing mit Vitest in JavaScript
~13 Min. Lesezeit Zuletzt aktualisiert am 8. August 2026
Zum Abschluss der praktischen Kapitel schreiben wir automatisierte Tests für unser Haushaltsbuch – dieselbe Testbibliothek (Vitest), die auch das TypeScript-Tutorial verwendet, funktioniert identisch mit reinem JavaScript.
Vitest installieren
npm install --save-dev vitest{
"name": "haushaltsbuch-app",
"version": "1.0.0",
"private": true,
"type": "module",
"scripts": {
"start": "node src/index.js",
"test": "vitest run"
},
"devDependencies": {
"vitest": "^2.1.0"
}
}Der erste Test
Vitest folgt der üblichen Konvention: Testdateien enden auf .test.js und liegen meist direkt neben der getesteten Datei:
import { describe, it, expect } from 'vitest';
import { istGueltigeKategorie, STANDARD_KATEGORIEN } from './kategorien.js';
describe('istGueltigeKategorie', () => {
it('gibt true für eine bekannte Kategorie zurück', () => {
expect(istGueltigeKategorie('Miete')).toBe(true);
});
it('gibt false für eine unbekannte Kategorie zurück', () => {
expect(istGueltigeKategorie('Unbekannt')).toBe(false);
});
it('enthält genau vier Standard-Kategorien', () => {
expect(STANDARD_KATEGORIEN).toHaveLength(4);
});
});npm testdescribe() gruppiert zusammengehörige Tests, it() (auch als test() aufrufbar) definiert einen EINZELNEN Testfall, expect() formuliert die eigentliche Behauptung ("Assertion").
Wichtige Matcher-Funktionen
toBe(wert)– exakte Gleichheit mit===, für Primitive geeignet.toEqual(objekt)– TIEFER Inhaltsvergleich bei Objekten/Arrays (denntoBewürde wegen Referenzvergleich aus Kapitel 12 fast immer fehlschlagen).toBeTruthy()/toBeFalsy()– Truthy/Falsy-Prüfung aus Kapitel 5.toThrow()– prüft, ob eine Funktion einen Error wirft.toHaveLength(n)– prüft die.length-Eigenschaft von Arrays/Strings.
import { describe, it, expect } from 'vitest';
function berechneSaldo(transaktionen) {
return transaktionen.reduce((summe, t) => summe + t.betrag, 0);
}
describe('berechneSaldo', () => {
it('summiert mehrere Transaktionen korrekt', () => {
const transaktionen = [{ betrag: 2400 }, { betrag: -850 }, { betrag: -60 }];
expect(berechneSaldo(transaktionen)).toBe(1490);
});
it('gibt 0 für ein leeres Array zurück', () => {
expect(berechneSaldo([])).toBe(0);
});
});Fehlerbehandlung testen
import { describe, it, expect } from 'vitest';
import { UngueltigeTransaktionFehler } from './fehler.js';
function validiereTransaktion(transaktion) {
if (!transaktion.beschreibung) {
throw new UngueltigeTransaktionFehler('Beschreibung fehlt');
}
}
describe('validiereTransaktion', () => {
it('wirft UngueltigeTransaktionFehler bei fehlender Beschreibung', () => {
expect(() => validiereTransaktion({ betrag: -18 })).toThrow(UngueltigeTransaktionFehler);
});
});Achtung: expect(() => ...) braucht bei toThrow() zwingend eine WRAPPER-Arrow-Function um den Aufruf. expect(validiereTransaktion(...)).toThrow() würde die Funktion SOFORT ausführen und den Fehler unkontrolliert werfen, statt ihn von Vitest kontrolliert einzufangen.
Asynchrone Funktionen testen
import { describe, it, expect } from 'vitest';
import { ladeTransaktionen } from './dateiSpeicher.js';
import { DateiNichtGefundenFehler } from './fehler.js';
describe('ladeTransaktionen', () => {
it('wirft DateiNichtGefundenFehler für eine fehlende Datei', async () => {
await expect(ladeTransaktionen('nicht-vorhanden.json')).rejects.toThrow(DateiNichtGefundenFehler);
});
});Die Testfunktion selbst wird async, und expect(...) wird mit await kombiniert – .rejects prüft dabei, dass das zurückgegebene Promise mit dem erwarteten Fehler ABGELEHNT wird, statt erfüllt zu werden.