Day 3 of 5

Integration Testing

Integration tests verify that multiple units work together — database queries, service calls, and HTTP handlers. Today you will test an Express API with Supertest and a real SQLite database.

bash
npm install --save-dev supertest
# Use jest with --testEnvironment=node for API tests
javascript
// app.js — Express app (exported without .listen)
import express from 'express';
const app = express();
app.use(express.json());

app.get('/users/:id', async (req, res) => {
  const user = await db.findUser(req.params.id);
  if (!user) return res.status(404).json({ error: 'Not found' });
  res.json(user);
});

app.post('/users', async (req, res) => {
  const { name, email } = req.body;
  if (!name || !email) return res.status(400).json({ error: 'Missing fields' });
  const user = await db.createUser({ name, email });
  res.status(201).json(user);
});

export default app;
javascript
// app.test.js
import request from 'supertest';
import app from './app';
import { db } from './db';

beforeAll(() => db.migrate());   // run migrations
afterEach(() => db.truncate());  // clean slate
afterAll(() => db.close());

describe('GET /users/:id', () => {
  test('returns 404 for unknown user', async () => {
    const res = await request(app).get('/users/999');
    expect(res.status).toBe(404);
    expect(res.body.error).toBe('Not found');
  });

  test('returns user by ID', async () => {
    const user = await db.createUser({ name: 'Bo', email: '[email protected]' });
    const res = await request(app).get(\`/users/\${user.id}\`);
    expect(res.status).toBe(200);
    expect(res.body.name).toBe('Bo');
  });
});

describe('POST /users', () => {
  test('creates a user', async () => {
    const res = await request(app)
      .post('/users')
      .send({ name: 'Alice', email: '[email protected]' });
    expect(res.status).toBe(201);
    expect(res.body).toHaveProperty('id');
  });

  test('rejects missing fields', async () => {
    const res = await request(app).post('/users').send({ name: 'No email' });
    expect(res.status).toBe(400);
  });
});

Exercise: Test an Express API

  1. Build a /tasks CRUD API with 4 routes
  2. Write integration tests for all 4 routes
  3. Use beforeAll to run DB migration
  4. Use afterEach to clear data between tests
  5. Assert status codes, response bodies, and DB state

Day 3 Summary

Finished this lesson?