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. Egal, ob Sie Webanwendungen mit Express, Koa, Fastify oder einem anderen Framework entwickeln: Supertest ist Ihr unverzichtbarer Helfer für zuverlässige Integrationstests.

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: Supertest testet den Server, ohne ihn auf einem echten Port starten zu müssen – die Bibliothek nutzt interne Node.js-Mechanismen zur Simulation der HTTP-Verbindung. Das macht Tests schnell und isoliert.

Warum Supertest? In der modernen Webentwicklung ist Codequalität entscheidend. Integrationstests, die Ihre API-Endpunkte prüfen, helfen, Regressionen, Fehler in der Anfrageverarbeitung und Validierungsprobleme frühzeitig 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 weiteren bekannten Projekten) und wird seitdem von der Community gepflegt. Supertest baut auf der Bibliothek SuperAgent auf – einem mächtigen HTTP-Client für Node.js und den Browser. Das bedeutet, Sie haben Zugriff auf alle SuperAgent-Funktionen, 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 TypeScript benötigen Sie möglicherweise auch die Typdefinitionen:

npm install --save-dev @types/supertest

Beachten Sie: Supertest erfordert Node.js Version 14 oder höher. 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 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. npx jest). Beide Tests sollten grün durchlaufen.

4. Wichtige Methoden im Detail

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

4.1 HTTP-Methoden

Supertest unterstützt alle gängigen HTTP-Methoden: .get(), .post(), .put(), .patch(), .delete(), .head() und .options(). Jede Methode erwartet den URL-Pfad als Argument.

await request(app).get('/api/users');
await request(app).post('/api/users');
await request(app).put('/api/users/1');
await request(app).delete('/api/users/1');

4.2 Anfrage-Daten senden

Mit .send() können Sie Daten im Anfragekörper übermitteln. Standardmäßig wird JSON erwartet, aber Sie können auch andere Formate verwenden.

await request(app)
  .post('/api/users')
  .send({ name: 'Jane Doe', email: 'jane@example.com' })
  .expect(201);

4.3 Header setzen

Mit .set() legen Sie benutzerdefinierte Header fest. Dies ist nützlich für Authentifizierung oder Content-Typ-Angaben.

await request(app)
  .get('/api/protected')
  .set('Authorization', 'Bearer token123')
  .expect(200);

4.4 Antworten prüfen

Die Methode .expect() ist das Herzstück von Supertest. Sie kann Statuscodes, Header, Antwortkörper oder benutzerdefinierte Funktionen prüfen.

// Statuscode prüfen
await request(app).get('/').expect(200);

// Header prüfen
await request(app).get('/').expect('Content-Type', /json/);

// Antwortkörper prüfen (mit Objektvergleich)
await request(app).get('/user').expect(200, { name: 'John Doe', age: 30 });

// Benutzerdefinierte Prüfung
await request(app)
  .get('/user')
  .expect((res) => {
    if (res.body.name !== 'John Doe') throw new Error('Falscher Name');
  });

5. Fortgeschrittene Techniken

5.1 Testen mit Authentifizierung

Viele APIs erfordern Authentifizierung. Mit Supertest können Sie Token oder Session-Cookies einfach setzen.

const agent = request.agent(app);

// Login durchführen
await agent
  .post('/login')
  .send({ username: 'admin', password: 'secret' })
  .expect(200);

// Geschützte Route mit aktiver Session testen
await agent
  .get('/api/dashboard')
  .expect(200);

5.2 Datei-Uploads testen

Supertest unterstützt auch Datei-Uploads über die .attach()-Methode.

const path = require('path');

await request(app)
  .post('/upload')
  .attach('avatar', path.join(__dirname, 'test-avatar.jpg'))
  .expect(200);

5.3 Asynchrone Tests mit async/await

Supertest funktioniert hervorragend mit async/await, wie in allen bisherigen Beispielen gezeigt. Alternativ können Sie auch Callbacks oder Promises verwenden.

// Mit Promise
it('should work with promises', () => {
  return request(app)
    .get('/')
    .expect(200);
});

// Mit Callback (nicht empfohlen)
it('should work with callbacks', (done) => {
  request(app)
    .get('/')
    .expect(200, done);
});

6. Fehlerbehandlung und Debugging

Wenn ein Test fehlschlägt, gibt Supertest detaillierte Fehlermeldungen aus. Typische Fehler sind:

  • Falscher Statuscode: Die erwartete Antwort weicht ab.
  • Falscher Content-Type: Der Header stimmt nicht mit der Erwartung überein.
  • Falscher Antwortkörper: Die JSON-Struktur oder Werte passen nicht.

Nutzen Sie .expect() mit einer benutzerdefinierten Funktion, um gezielt zu debuggen:

await request(app)
  .get('/api/users')
  .expect((res) => {
    console.log('Response body:', JSON.stringify(res.body, null, 2));
    if (!Array.isArray(res.body)) {
      throw new Error('Antwort sollte ein Array sein');
    }
  });

7. Fazit

Supertest ist ein unverzichtbares Werkzeug für jeden Node.js-Entwickler, der qualitativ hochwertige APIs baut. Mit seiner einfachen API, der nahtlosen Integration in Test-Runner und der Unterstützung für alle HTTP-Features macht es das Testen von Endpunkten zum Kinderspiel. Ob Sie eine kleine Express-App oder eine komplexe Microservice-Architektur testen – Supertest liefert die Geschwindigkeit und Flexibilität, die Sie brauchen.

Beginnen Sie noch heute mit Supertest und bringen Sie Ihre API-Tests auf das nächste Level! Weitere Ressourcen und Beispiele finden Sie in der offiziellen Dokumentation auf GitHub.

Empfehlungen