0
0
ExpressHow-ToBeginner · 4 min read

How to Use Supertest with Express for API Testing

Use supertest by importing it and passing your Express app to it. Then, chain HTTP methods like .get() or .post() with assertions to test your API endpoints easily.
📐

Syntax

The basic syntax involves importing supertest and your Express app, then calling request(app) to start a test. You chain HTTP methods like .get(path) or .post(path) and use .expect() to check status codes or response data.

  • request(app): Initializes Supertest with your Express app.
  • .get('/path'): Sends a GET request to the specified path.
  • .post('/path'): Sends a POST request.
  • .expect(status): Checks the HTTP status code.
  • .expect(body): Checks the response body.
  • .end(callback): Optional callback to finish the test.
javascript
import request from 'supertest';
import app from './app';

describe('GET /endpoint', () => {
  it('responds with status 200', async () => {
    await request(app)
      .get('/endpoint')
      .expect(200)
      .expect('Content-Type', /json/);
  });
});
💻

Example

This example shows a simple Express app with one GET route and a test using Supertest to check if the route returns status 200 and the expected JSON response.

javascript
import express from 'express';
import request from 'supertest';

const app = express();

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

describe('GET /hello', () => {
  it('should respond with JSON containing message', async () => {
    const response = await request(app)
      .get('/hello')
      .expect('Content-Type', /json/)
      .expect(200);

    expect(response.body).toEqual({ message: 'Hello, world!' });
  });
});
Output
PASS ./app.test.js GET /hello ✓ should respond with JSON containing message (XX ms) Test Suites: 1 passed, 1 total Tests: 1 passed, 1 total Snapshots: 0 total Time: XX s
⚠️

Common Pitfalls

  • Not exporting your Express app properly can cause Supertest to fail.
  • Forgetting to use await or return the Supertest call in async tests can make tests pass incorrectly.
  • Not setting Content-Type headers when sending JSON requests can cause unexpected failures.
  • Using .end() callback and async/await together can cause confusion; prefer async/await for clarity.
javascript
/* Wrong: Missing await, test may pass without running request */
test('GET /hello missing await', () => {
  return request(app)
    .get('/hello')
    .expect(200);
});

/* Right: Using await to ensure test waits for request */
test('GET /hello with await', async () => {
  await request(app)
    .get('/hello')
    .expect(200);
});
📊

Quick Reference

Here is a quick summary of common Supertest methods used with Express:

MethodDescription
request(app)Initialize Supertest with your Express app
.get(path)Send a GET request to the path
.post(path)Send a POST request to the path
.send(data)Send JSON or form data in the request body
.set(header, value)Set HTTP headers for the request
.expect(status)Assert the HTTP status code
.expect(header, value)Assert a response header
.expect(body)Assert the response body content
.end(callback)Optional callback to finish the test

Key Takeaways

Import Supertest and pass your Express app to start testing endpoints.
Use async/await with Supertest calls to ensure tests run correctly.
Check status codes and response bodies with .expect() methods.
Export your Express app without listening to allow Supertest to handle requests.
Avoid mixing callbacks and async/await for clearer test code.