Databases, Testing, and DeploymentLesson 6.3
Integration testing Express APIs with Supertest
supertest setup, testing routes without starting a server, status code assertions, body assertions, authentication in tests, beforeAll/afterAll, test isolation
Test the Full HTTP Layer Without a Running Server
Supertest makes HTTP calls directly to your Express app in-process — no need to run a server on a port. This makes tests fast and isolated.
npm install supertest --save-dev// app.js — export app without calling listen
const express = require('express');
const app = express();
app.use(express.json());
app.get('/api/health', (req, res) => res.json({ status: 'ok' }));
app.post('/api/users', (req, res) => {
if (!req.body.name) return res.status(400).json({ error: 'Name required' });
res.status(201).json({ id: 1, ...req.body });
});
module.exports = app;// app.test.js
const request = require('supertest');
const app = require('./app');
describe('GET /api/health', () => {
it('returns 200 with status ok', async () => {
const res = await request(app).get('/api/health');
expect(res.status).toBe(200);
expect(res.body.status).toBe('ok');
});
});
describe('POST /api/users', () => {
it('creates a user with valid data', async () => {
const res = await request(app)
.post('/api/users')
.send({ name: 'Alice', email: 'alice@test.com' });
expect(res.status).toBe(201);
expect(res.body).toMatchObject({ name: 'Alice' });
});
it('returns 400 when name is missing', async () => {
const res = await request(app).post('/api/users').send({});
expect(res.status).toBe(400);
});
});