Testen in TypeScript: Unit-, Integrations- und E2E-Tests von A bis Z

Online Python-Trainer für Anfänger

Lernen Sie Python einfach ohne theoretische Überlastung. Lösen Sie praktische Aufgaben mit automatischer Überprüfung und schreiben Sie Code direkt im Browser.

Kurs starten

Einleitung: Warum Testing in TypeScript ein Must-have ist

TypeScript ist ein leistungsstarkes Werkzeug, das JavaScript um statische Typisierung erweitert. Allerdings garantiert selbst das strengste Typsystem nicht, dass Ihr Code zur Laufzeit korrekt funktioniert. Bugs, logische Fehler, fehlerhafte Behandlung von Randfällen – all das bleibt außerhalb der Kompilierung. Hier kommt das Testen ins Spiel.

In diesem Artikel werden wir drei grundlegende Testebenen in TypeScript behandeln: Unit-Tests, Integrationstests und E2E-Tests (End-to-End). Sie erfahren, wie sie sich unterscheiden, wann welche anzuwenden ist, und sehen reale Codebeispiele. Nach der Lektüre können Sie eine vollständige Test-Pipeline für Ihr TypeScript-Projekt einrichten.



1. Unit-Tests: Überprüfung atomarer Code-Einheiten

Unit-Tests sind die schnellste und günstigste Testebene. Sie isolieren eine einzelne Funktion, Methode oder Klasse und testen sie unabhängig von externen Abhängigkeiten (Datenbanken, APIs, Dateisystem).



1.1 Werkzeugauswahl und Einrichtung

Das beliebteste Framework für TypeScript ist Jest. Es bietet integrierte TypeScript-Unterstützung über ts-jest oder @swc/jest.

// Installationnpm install --save-dev jest @types/jest ts-jest

// Konfigurationsinitialisierungnpx ts-jest config:init

Danach erscheint im Stammverzeichnis die Datei jest.config.js mit den Einstellungen.



1.2 Beispiel eines Unit-Tests für eine Funktion

Angenommen, wir haben eine einfache Funktion zur Berechnung eines Rabatts:

// discount.tsexport function applyDiscount(price: number, discountPercent: number): number {  if (discountPercent < 0 || discountPercent > 100) {    throw new Error('Ungültiger Rabattprozentsatz');  }  return price - (price * discountPercent) / 100;}

Schreiben wir einen Unit-Test dafür:

// discount.test.tsimport { applyDiscount } from './discount';

describe('applyDiscount', () => { it('sollte einen Rabatt von 10% korrekt berechnen', () => { expect(applyDiscount(1000, 10)).toBe(900); });

it('sollte den ursprünglichen Preis bei 0% Rabatt zurückgeben', () => { expect(applyDiscount(500, 0)).toBe(500); });

it('sollte einen Fehler bei einem Rabatt über 100% werfen', () => { expect(() => applyDiscount(100, 150)).toThrow('Ungültiger Rabattprozentsatz'); });});

Ausführen mit: npx jest. Alle drei Tests sollten grün durchlaufen.



1.3 Mocks und Stubs

Wenn eine Funktion auf einen externen Dienst zugreift (z. B. eine Datenbank), ersetzen wir ihn durch einen Mock:

// userService.test.tsimport { getUser } from './userService';import { db } from './database';

jest.mock('./database'); // Automatischer Mock

test('getUser gibt einen Benutzer anhand der ID zurück', async () => { (db.findUser as jest.Mock).mockResolvedValue({ id: 1, name: 'Ivan' }); const user = await getUser(1); expect(user.name).toBe('Ivan');});


2. Integrationstests: Überprüfung der Modulinteraktion

Integrationstests prüfen, wie verschiedene Teile des Systems zusammenarbeiten: Controller, Services, Repositories, Datenbanken. Sie sind langsamer als Unit-Tests, geben aber mehr Vertrauen in die Korrektheit der Verbindungen.



2.1 Testen eines API-Endpunkts mit Express

Zum Testen von HTTP-Anfragen verwenden wir die Bibliothek Supertest zusammen mit Jest.

// Installationnpm install --save-dev supertest @types/supertest

Angenommen, wir haben eine Express-Anwendung:

// app.tsimport express from 'express';import { createUser } from './controllers/userController';

export const app = express();app.use(express.json());app.post('/api/users', createUser);

Integrationstest:

// app.test.tsimport request from 'supertest';import { app } from './                

Blogs

Buchempfehlungen