Zum Inhalt

_

_

_

SuperTest Cheatsheet

• Installation

Platform Command
npm (All Platforms) INLINE_CODE_20
Yarn (All Platforms) INLINE_CODE_21
With Jest INLINE_CODE_22
With Mocha INLINE_CODE_23
With TypeScript INLINE_CODE_24
Specific Version INLINE_CODE_25
_
Standard HTTP Methoden
Command Description
INLINE_CODE_26 Send GET request to endpoint
INLINE_CODE_27 Send POST request to endpoint
INLINE_CODE_28 Send PUT request to update resource
INLINE_CODE_29 Send PATCH request for partial update
INLINE_CODE_30 Send DELETE request to remove resource
INLINE_CODE_31 Send HEAD request (headers only)
INLINE_CODE_32 Send OPTIONS request for CORS preflight
INLINE_CODE_33 Send JSON data in request body
INLINE_CODE_34 Add query parameters to URL
INLINE_CODE_35 Set request header
INLINE_CODE_36 Assert HTTP status code
INLINE_CODE_37 Assert response header value
INLINE_CODE_38 Execute request with callback
INLINE_CODE_39 Execute request with Promise/async-await
_
Beschwörungen und Erwartungen
Command Description
INLINE_CODE_40 Expect exact status code
INLINE_CODE_41 Expect status and exact body match
INLINE_CODE_42 Expect exact header value
INLINE_CODE_43 Expect header matching regex
INLINE_CODE_44 Custom assertion function
INLINE_CODE_45 Expect status and body matching regex
INLINE_CODE_46 Expect redirect location header
INLINE_CODE_47 Expect exact JSON body match

Konfiguration anfordern

Command Description
INLINE_CODE_48 Set single request header
INLINE_CODE_49 Set multiple headers
INLINE_CODE_50 Set HTTP Basic Authentication
INLINE_CODE_51 Add form field (multipart)
INLINE_CODE_52 Attach file for upload
INLINE_CODE_53 Attach file from buffer
INLINE_CODE_54 Set request timeout in milliseconds
INLINE_CODE_55 Follow up to 5 redirects
INLINE_CODE_56 Set Content-Type header
INLINE_CODE_57 Set Accept header
INLINE_CODE_58 Send raw string body
INLINE_CODE_59 Send binary data
_
/ Fortgeschrittene Nutzung
Command Description
INLINE_CODE_60 Create agent for persistent cookies
INLINE_CODE_61 Use agent for authenticated requests
INLINE_CODE_62 Test external API endpoints
INLINE_CODE_63 Custom response parser
INLINE_CODE_64 Buffer response body
INLINE_CODE_65 Set expected response type
INLINE_CODE_66 Retry failed requests 3 times
INLINE_CODE_67 Set custom CA certificate
INLINE_CODE_68 Set client certificate
INLINE_CODE_69 Set client private key
INLINE_CODE_70 Set PFX/PKCS12 certificate
INLINE_CODE_71 Disable TLS certificate validation

Testen von Mustern

Pattern Description
INLINE_CODE_72 Store response for multiple assertions
INLINE_CODE_73 Assert on response body with test framework
INLINE_CODE_74 Assert on response headers
INLINE_CODE_75 Alternative status assertion
INLINE_CODE_76 Parallel request testing
INLINE_CODE_77 Sequential test requests
_
Konfiguration

Basic Test Setup

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

module.exports = { request, app };

Jest Konfiguration

// jest.config.js
module.exports = {
  testEnvironment: 'node',
  testMatch: ['**/__tests__/**/*.test.js'],
  collectCoverageFrom: ['src/**/*.js'],
  coveragePathIgnorePatterns: ['/node_modules/']
};

Mocha Konfiguration

// test/mocha.opts
--require test/setup.js
--recursive
--timeout 5000
--exit

Paket.json Scripts

{
  "scripts": {
    "test": "jest",
    "test:watch": "jest --watch",
    "test:coverage": "jest --coverage",
    "test:api": "jest --testPathPattern=api"
  }
}

Umgebungsvariablen

// config/test.js
module.exports = {
  port: process.env.TEST_PORT || 3001,
  database: process.env.TEST_DB || 'test_db',
  apiTimeout: process.env.API_TIMEOUT || 5000
};

Häufige Anwendungsfälle

Use Case 1: Testen von REST API CRUD Operationen

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

describe('User API', () => {
  let userId;

  // Create
  test('POST /api/users - create user', async () => {
    const res = await request(app)
      .post('/api/users')
      .send({ name: 'John Doe', email: 'john@example.com' })
      .expect(201)
      .expect('Content-Type', /json/);

    userId = res.body.id;
    expect(res.body.name).toBe('John Doe');
  });

  // Read
  test('GET /api/users/:id - get user', async () => {
    await request(app)
      .get(`/api/users/${userId}`)
      .expect(200)
      .expect((res) => {
        expect(res.body.name).toBe('John Doe');
      });
  });

  // Update
  test('PUT /api/users/:id - update user', async () => {
    await request(app)
      .put(`/api/users/${userId}`)
      .send({ name: 'Jane Doe' })
      .expect(200);
  });

  // Delete
  test('DELETE /api/users/:id - delete user', async () => {
    await request(app)
      .delete(`/api/users/${userId}`)
      .expect(204);
  });
});

Use Case 2: Testing Authentication Flow

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

describe('Authentication', () => {
  let authToken;

  test('POST /auth/register - register new user', async () => {
    await request(app)
      .post('/auth/register')
      .send({
        email: 'test@example.com',
        password: 'SecurePass123!',
        name: 'Test User'
      })
      .expect(201);
  });

  test('POST /auth/login - login user', async () => {
    const res = await request(app)
      .post('/auth/login')
      .send({
        email: 'test@example.com',
        password: 'SecurePass123!'
      })
      .expect(200)
      .expect('Content-Type', /json/);

    authToken = res.body.token;
    expect(authToken).toBeDefined();
  });

  test('GET /api/profile - access protected route', async () => {
    await request(app)
      .get('/api/profile')
      .set('Authorization', `Bearer ${authToken}`)
      .expect(200)
      .expect((res) => {
        expect(res.body.email).toBe('test@example.com');
      });
  });

  test('GET /api/profile - reject without token', async () => {
    await request(app)
      .get('/api/profile')
      .expect(401);
  });
});

Use Case 3: Dateiaufladung testen

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

describe('File Upload', () => {
  test('POST /api/upload - upload single file', async () => {
    const filePath = path.join(__dirname, 'fixtures', 'test.pdf');

    const res = await request(app)
      .post('/api/upload')
      .attach('document', filePath)
      .field('title', 'Test Document')
      .field('description', 'A test file upload')
      .expect(200)
      .expect('Content-Type', /json/);

    expect(res.body.filename).toMatch(/\.pdf$/);
    expect(res.body.size).toBeGreaterThan(0);
  });

  test('POST /api/upload - upload multiple files', async () => {
    await request(app)
      .post('/api/upload/multiple')
      .attach('files', 'test/fixtures/file1.pdf')
      .attach('files', 'test/fixtures/file2.pdf')
      .expect(200)
      .expect((res) => {
        expect(res.body.files).toHaveLength(2);
      });
  });
});

Use Case 4: Prüfung mit dauerhaften Sitzungen

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

describe('Session Management', () => {
  const agent = request.agent(app);

  test('Login and maintain session', async () => {
    // Login
    await agent
      .post('/auth/login')
      .send({ username: 'user', password: 'pass' })
      .expect(200);

    // Session persists - can access protected route
    await agent
      .get('/api/dashboard')
      .expect(200);

    // Session still valid for subsequent requests
    await agent
      .get('/api/profile')
      .expect(200);

    // Logout
    await agent
      .post('/auth/logout')
      .expect(200);

    // Session expired - access denied
    await agent
      .get('/api/dashboard')
      .expect(401);
  });
});

Use Case 5: Testfehlerbehandlung

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

describe('Error Handling', () => {
  test('404 - Resource not found', async () => {
    await request(app)
      .get('/api/users/99999')
      .expect(404)
      .expect((res) => {
        expect(res.body.error).toBe('User not found');
        expect(res.body.code).toBe('USER_NOT_FOUND');
      });
  });

  test('400 - Validation error', async () => {
    await request(app)
      .post('/api/users')
      .send({ name: '' }) // Invalid data
      .expect(400)
      .expect((res) => {
        expect(res.body.errors).toBeDefined();
        expect(res.body.errors.name).toContain('required');
      });
  });

  test('429 - Rate limit exceeded', async () => {
    // Make multiple requests to trigger rate limit
    const requests = Array(101).fill().map(() =>
      request(app).get('/api/users')
    );

    const responses = await Promise.all(requests);
    const rateLimited = responses.find(r => r.status === 429);

    expect(rateLimited).toBeDefined();
    expect(rateLimited.body.error).toMatch(/rate limit/i);
  });

  test('500 - Internal server error', async () => {
    await request(app)
      .get('/api/trigger-error')
      .expect(500)
      .expect((res) => {
        expect(res.body.error).toBe('Internal server error');
      });
  });
});

oder Best Practices

  • ** Verwenden Sie async/await syntax**: Reiniger und lesbarer als Callbacks. Modern JavaScript unterstützt dieses Muster native. javascript const res = await request(app).get('/api/users').expect(200);_

  • **Installieren als dev Abhängigkeit*: SuperTest ist ein Test-Tool und sollte nur in devDependencies sein, nicht Produktionsabhängigkeiten. bash npm install supertest --save-dev_

  • ** Starten Sie den Server nicht manuell*: SuperTest behandelt die Serverbindung automatisch. Passen Sie die Express-App direkt ohne Anruf app.listen(). ```javascript // Good: Export app without listening module.exports = app;

// Bad: Don't do this in test files app.listen(3000); ```_

  • **Beantragung.agent() für Sitzungstests*: Wenn Sie authentische Routen oder Cookie-basierte Sitzungen testen, erstellen Sie einen Agenten, um Cookies auf Anfrage zu bestehen. javascript const agent = request.agent(app); await agent.post('/login').send(credentials); await agent.get('/protected'); // Cookies persist_

  • ** Erwartungen für sauberere Tests*: Mehrere .expect() Anrufe können in einem einzigen Test für umfassende Behauptungen gekettet werden. javascript await request(app) .get('/api/users') .expect(200) .expect('Content-Type', /json/) .expect((res) => expect(res.body).toHaveLength(10));_

  • **Store Antworten für komplexe Behauptungen*: Erfassen Sie das Antwortobjekt, wenn Sie mehrere Behauptungen auf verschiedenen Teilen durchführen müssen. javascript const res = await request(app).get('/api/users').expect(200); expect(res.body).toHaveLength(5); expect(res.headers['x-total-count']).toBe('100');_

  • ** Testen Sie beide Erfolgs- und Ausfallfälle*: Testen Sie immer Fehlerszenarien, Validierungsfehler und Randfälle entlang glücklicher Pfade. javascript test('returns 404 for non-existent user', async () => { await request(app).get('/api/users/99999').expect(404); });_

  • **Benutze beschreibende Testnamen*: Testbeschreibungen schreiben, die deutlich erklären, welches Verhalten überprüft wird. javascript test('POST /api/users returns 400 when email is missing', async () => { // Test implementation });_

  • ** Prüfdaten nach oben*: Verwenden Sie beforeEachafterEach, um den Datenbankzustand zurückzusetzen und die Testisolation zu gewährleisten. javascript afterEach(async () => { await User.deleteMany({}); });

  • **Stimmen einstellen*: Für langsame Endpunkte oder externe API-Anrufe konfigurieren Sie Timeout-Werte, um Fehlausfälle zu verhindern. javascript await request(app).get('/api/slow').timeout(10000).expect(200);_

Fehlerbehebung

Issue Solution
INLINE_CODE_83 Don't call INLINE_CODE_84 in your app file when testing. Export the app without starting the server, or use different ports for testing.
Tests hang and never complete Ensure database connections are closed after tests. Use INLINE_CODE_85 to close connections: INLINE_CODE_86
INLINE_CODE_87 Missing INLINE_CODE_88 keyword or INLINE_CODE_89 callback. Always use INLINE_CODE_90 with async/await or provide INLINE_CODE_91 callback.
Headers already sent error You're sending multiple responses in your route handler. Ensure only one INLINE_CODE_92, INLINE_CODE_93, or similar call per request.
Timeout errors on slow endpoints Increase timeout with INLINE_CODE_94 or adjust global timeout in test framework config: INLINE_CODE_95
Authentication tests fail randomly Use INLINE_CODE_96 to persist cookies/sessions across requests instead of separate INLINE_CODE_97 calls.
File upload tests fail Verify file path is correct using INLINE_CODE_98. Ensure multipart middleware is configured in app.
CORS errors in tests CORS is typically a browser concern. SuperTest bypasses CORS. If testing CORS headers, use INLINE_CODE_99 request with Origin header.
SSL/TLS certificate errors Use INLINE_CODE_100 for testing environments or provide valid certificates with INLINE_CODE_101, INLINE_CODE_102, INLINE_CODE_103 methods.
Response body is empty Buffer Response might be binary. Use INLINE_CODE_104 or check Content-Type. For JSON, ensure server sends correct Content-Type header.
Tests pass individually but fail together Tests aren't isolated. Clear database/state between tests using INLINE_CODE_105/INLINE_CODE_106 hooks. Check for shared mutable state.
Kann externe APIs nicht testen SuperTest funktioniert mit externen URLs: __INLINE_CODE_107_. Stellen Sie sicher, dass Netzwerkzugriff und API-Verfügbarkeit.