Script Valley
REST API Development: Complete Course from Beginner to Production
Building REST APIs with Express.jsLesson 3.5

Testing REST APIs: Unit Tests and Integration Tests

API testing, Jest, Supertest, unit testing controllers, integration testing endpoints, test database, test coverage, mocking, TDD

Testing REST APIs: Unit Tests and Integration Tests

Untested REST APIs are technical debt waiting to explode. Every endpoint change risks breaking existing clients. A comprehensive test suite catches regressions before deployment, documents expected behavior, and gives you confidence to refactor.

DiagramAPI Testing Strategy Pyramid

IMAGE PROMPT (replace this block with your generated image):

Flat testing pyramid infographic on white background. Title: REST API Testing Strategy. A large triangle divided into three horizontal sections from bottom to top. Bottom section (widest): Unit Tests — fill light #3A5EFF (#e8ecff), text: Test individual functions, validators, utilities. Label: Fast, Many, Isolated. Middle section: Integration Tests — fill medium #3A5EFF (#b3c5ff), text: Test full endpoints with Supertest + DB. Label: Moderate speed, Core coverage. Top section (narrowest): End-to-End Tests — fill solid #3A5EFF with white text, text: Full user flows. Label: Slow, Few, High value. Right side of pyramid: vertical annotations with arrows pointing to each layer. Bottom annotation: Jest unit tests for services and validators. Middle annotation: Supertest for HTTP endpoint testing. Top annotation: Postman / Playwright. At the base of the pyramid: badge showing 80% coverage target. Clean, educational style, white background.

Setting Up Jest and Supertest

npm install --save-dev jest supertest

Add to package.json:

"scripts": {
  "test": "jest --coverage",
  "test:watch": "jest --watchAll"
},
"jest": {
  "testEnvironment": "node",
  "coverageThreshold": {
    "global": { "lines": 80 }
  }
}

Integration Testing with Supertest

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

describe('GET /api/users', () => {
  it('should return 200 and a list of users', async () => {
    const res = await request(app)
      .get('/api/users')
      .set('Authorization', `Bearer ${testToken}`);

    expect(res.statusCode).toBe(200);
    expect(res.body.success).toBe(true);
    expect(Array.isArray(res.body.data)).toBe(true);
  });

  it('should return 401 without authentication', async () => {
    const res = await request(app).get('/api/users');
    expect(res.statusCode).toBe(401);
  });
});

What to Test

Test the happy path (successful operations), all error conditions (400, 401, 403, 404, 409, 422), edge cases (empty arrays, null values, boundary values), and authorization (that users cannot access resources they should not). Every endpoint should have at least three tests: success, not-found, and unauthorized.