Supertest für JavaScript (Node.js): Komplettguide mit Beispielen

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

Supertest für JavaScript (Node.js): Komplettguide mit Beispielen

Willkommen bei PythonLib! In diesem Artikel tauchen wir tief in die Bibliothek Supertest ein – eines der beliebtesten Tools für HTTP-Tests im Node.js-Ökosystem. Ob Sie Webanwendungen mit Express, Koa, Fastify oder einem anderen Framework entwickeln, Supertest wird Ihr unverzichtbarer Helfer für zuverlässige Integrationstests sein.

1. Was ist Supertest und warum braucht man es?

Supertest ist eine leistungsstarke Bibliothek zum Testen von HTTP-Servern in Node.js. Sie bietet eine klare und ausdrucksstarke API, um HTTP-Anfragen an Ihre Anwendung zu senden und die Antworten zu prüfen. Die Besonderheit von Supertest: Sie können Ihren Server testen, ohne ihn auf einem echten Port starten zu müssen – die Bibliothek nutzt interne Node.js-Mechanismen zur Simulation der HTTP-Verbindung, was Tests schnell und isoliert macht.

Warum Supertest? In der modernen Webentwicklung ist Codequalität entscheidend. Integrationstests, die Ihre API-Endpunkte prüfen, helfen, Regressionen, Fehler in der Anfrageverarbeitung und Probleme bei der Datenvalidierung zu erkennen. Supertest ermöglicht es, solche Tests prägnant und lesbar zu schreiben – mit Methodenverkettung (Chaining) und integrierten Assertions für Statuscodes, Header, Antwortkörper und mehr. Die Bibliothek harmoniert perfekt mit Test-Runnern wie Jest, Mocha, Jasmine und AVA.

Entwickelt wurde Supertest von TJ Holowaychuk (Autor von Express, Koa und vielen anderen bekannten Projekten) und wird seitdem von der Community gepflegt. Supertest baut auf der Bibliothek SuperAgent auf – einem leistungsfähigen HTTP-Client für Node.js und den Browser. Das bedeutet, Sie haben Zugriff auf alle Funktionen von SuperAgent, inklusive Unterstützung für verschiedene Datentypen, Datei-Uploads, Cookie-Handling und vieles mehr.

2. Installation

Die Installation von Supertest erfolgt über den Paketmanager npm. Es wird empfohlen, die Bibliothek als Entwicklungsabhängigkeit (devDependency) zu installieren, da sie in der Produktion nicht benötigt wird.

npm install --save-dev supertest

Wenn Sie yarn verwenden:

yarn add --dev supertest

Für die Arbeit mit TypeScript benötigen Sie möglicherweise auch die Typdefinitionen:

npm install --save-dev @types/supertest

Beachten Sie, dass Supertest Node.js Version 14 oder höher erfordert. Stellen Sie außerdem sicher, dass ein Test-Runner (z. B. Jest oder Mocha) installiert ist.

3. Schnellstart – Minimales Arbeitsbeispiel

Lassen Sie uns eine einfache Express-Anwendung erstellen und einen Test mit Supertest dafür schreiben. Dieses Beispiel zeigt die grundlegende Funktionsweise der Bibliothek.

Zuerst erstellen wir die Datei app.js mit unserer Anwendung:

// app.js
const express = require('express');
const app = express();

app.get('/', (req, res) => {
  res.status(200).json({ message: 'Hello, World!' });
});

app.get('/user', (req, res) => {
  res.status(200).json({ name: 'John Doe', age: 30 });
});

module.exports = app;

Jetzt erstellen wir die Testdatei app.test.js:

// app.test.js
const request = require('supertest');
const app = require('./app');

describe('GET /', () => {
  it('should return Hello, World!', async () => {
    const response = await request(app)
      .get('/')
      .expect(200);

    expect(response.body).toEqual({ message: 'Hello, World!' });
  });
});

describe('GET /user', () => {
  it('should return user data', async () => {
    const response = await request(app)
      .get('/user')
      .expect('Content-Type', /json/)
      .expect(200);

    expect(response.body.name).toBe('John Doe');
    expect(response.body.age).toBe(30);
  });
});

Führen Sie den Test mit Ihrem Test-Runner aus, z. B. mit Jest:

npx jest app.test.js

Sie sollten eine Erfolgsmeldung sehen, die bestätigt, dass beide Tests bestanden wurden.

4. Wichtige Methoden im Überblick

Supertest bietet eine Vielzahl von Methoden, um HTTP-Anfragen zu senden und Antworten zu prüfen. Hier sind die wichtigsten:

HTTP-Methoden

  • .get(url) – sendet eine GET-Anfrage
  • .post(url) – sendet eine POST-Anfrage
  • .put(url) – sendet eine PUT-Anfrage
  • .patch(url) – sendet eine PATCH-Anfrage
  • .delete(url) – sendet eine DELETE-Anfrage
  • .head(url) – sendet eine HEAD-Anfrage
  • .options(url) – sendet eine OPTIONS-Anfrage

Anfrage-Konfiguration

  • .set(field, value) – setzt einen HTTP-Header
  • .send(data) – sendet Daten im Anfragekörper (für POST, PUT, PATCH)
  • .query(params) – fügt Query-Parameter hinzu
  • .auth(username, password) – fügt Basic-Authentifizierung hinzu
  • .attach(field, path) – hängt eine Datei an (für Datei-Uploads)
  • .field(name, value) – fügt ein Formularfeld hinzu

Antwort-Prüfung

  • .expect(status) – prüft den HTTP-Statuscode
  • .expect(header, value) – prüft einen bestimmten Header
  • .expect(body) – prüft den Antwortkörper (teilweise oder vollständig)
  • .expect(fn) – benutzerdefinierte Prüffunktion
  • .end(fn) – beendet die Anfrage und ruft einen Callback auf (für asynchrone Tests ohne async/await)

5. Fortgeschrittene Beispiele

POST-Anfrage mit JSON-Daten

describe('POST /users', () => {
  it('should create a new user', async () => {
    const newUser = { name: 'Jane Doe', email: 'jane@example.com' };
    
    const response = await request(app)
      .post('/users')
      .send(newUser)
      .set('Content-Type', 'application/json')
      .expect(201);

    expect(response.body).toHaveProperty('id');
    expect(response.body.name).toBe('Jane Doe');
  });
});

Authentifizierte Anfrage

describe('GET /protected', () => {
  it('should return data with valid token', async () => {
    const token = 'mein-geheimer-token';
    
    const response = await request(app)
      .get('/protected')
      .set('Authorization', `Bearer ${token}`)
      .expect(200);

    expect(response.body).toHaveProperty('data');
  });

  it('should return 401 without token', async () => {
    await request(app)
      .get('/protected')
      .expect(401);
  });
});

Datei-Upload testen

describe('POST /upload', () => {
  it('should upload a file', async () => {
    const response = await request(app)
      .post('/upload')
      .attach('avatar', 'path/to/test-image.jpg')
      .expect(200);

    expect(response.body).toHaveProperty('filename');
  });
});

6. Tipps für die Praxis

  • Test-Isolation: Stellen Sie sicher, dass jeder Test unabhängig ist. Verwenden Sie beforeEach, um den Zustand zurückzusetzen (z. B. Datenbank leeren).
  • Fehlerbehandlung: Testen Sie nicht nur den Erfolgsfall, sondern auch Fehlerfälle (404, 400, 500 usw.).
  • Asynchrone Tests: Nutzen Sie async/await für sauberen und lesbaren Code. Vergessen Sie nicht, await vor request(...) zu setzen.
  • Kombination mit Jest: Jest bietet tolle Funktionen wie toMatchSnapshot() für API-Antworten oder toContain() für Arrays.
  • Umgebungsvariablen: Nutzen Sie verschiedene Konfigurationen für Test- und Produktionsumgebungen (z. B. über .env.test).

7. Fazit

Supertest ist ein unverzichtbares Werkzeug für jeden Node.js-Entwickler, der qualitativ hochwertige Webanwendungen bauen möchte. Mit seiner einfachen API, der nahtlosen Integration in gängige Test-Runner und der Unterstützung für alle wichtigen HTTP-Features macht es das Testen von APIs zum Kinderspiel. Ob Sie ein kleines Projekt oder eine große Microservices-Architektur testen – Supertest ist die richtige Wahl.

Haben Sie Fragen oder Anregungen? Hinterlassen Sie einen Kommentar! Und vergessen Sie nicht, PythonLib für weitere Tutorials zu Node.js, JavaScript und moderner Webentwicklung zu folgen.

Empfehlungen