Supertest for Node.js API Testing
In this tutorial, you will learn about Supertest for Node.js API Testing. We cover key concepts, practical examples, and best practices to help you master this topic.
Supertest is a Node.js library for testing HTTP APIs. It wraps the SuperAgent HTTP client and provides a fluent API for making requests and asserting responses. It integrates with any test framework (Jest, Mocha, AVA).
What You'll Learn
- Supertest setup and basic usage
- Testing GET, POST, PUT, DELETE endpoints
- Authentication and header manipulation
- File upload testing
- Integration with Jest
Why It Matters
Supertest is the most popular Node.js API testing library. It tests Express, Koa, Fastify, and other frameworks without running a separate server. It provides a clean, chainable API for assertions.
Real-World Use
Express.js documentation uses Supertest for examples. NestJS testing guides recommend Supertest. Many Node.js open-source projects use Supertest with Jest.
flowchart LR
Test[Jest Test] --> Supertest[Supertest Request]
Supertest --> App[Express App]
App --> Route[Route Handler]
Route --> Response[Response]
Supertest --> Assert[Assertions]
Assert --> Pass[Test Pass/Fail]
Teacher Mindset
Supertest injects requests into your Express app without starting a server. This makes tests fast and parallelizable. Chain methods for request configuration and use .expect() for assertions.
Code Examples
// Example 1: Basic Supertest with Jest
const request = require('supertest');
const app = require('../app');
describe('GET /api/users', () => {
it('returns all users', async () => {
const res = await request(app)
.get('/api/users')
.expect('Content-Type', /json/)
.expect(200);
expect(res.body).toBeInstanceOf(Array);
expect(res.body.length).toBeGreaterThan(0);
});
it('returns 404 for non-existent user', async () => {
const res = await request(app)
.get('/api/users/999')
.expect(404);
expect(res.body).toHaveProperty('error', 'User not found');
});
});
// Example 2: Authenticated requests
describe('POST /api/users', () => {
it('creates a new user', async () => {
const res = await request(app)
.post('/api/users')
.send({ name: 'Alice', email: 'alice@test.com' })
.set('Authorization', 'Bearer ' + adminToken)
.expect(201);
expect(res.body).toHaveProperty('id');
expect(res.body.name).toBe('Alice');
});
it('rejects duplicate email', async () => {
await request(app)
.post('/api/users')
.send({ name: 'Bob', email: 'alice@test.com' })
.set('Authorization', 'Bearer ' + adminToken)
.expect(409);
});
});
// Example 3: File upload and cookie testing
describe('File upload', () => {
it('uploads a file', async () => {
const res = await request(app)
.post('/api/upload')
.attach('avatar', 'test/fixtures/avatar.jpg')
.expect(200);
expect(res.body).toHaveProperty('url');
});
});
describe('Cookie-based auth', () => {
it('accesses protected route with cookie', async () => {
const loginRes = await request(app)
.post('/api/auth/login')
.send({ username: 'admin', password: 'secret' });
const cookies = loginRes.headers['set-cookie'];
const res = await request(app)
.get('/api/users/me')
.set('Cookie', cookies)
.expect(200);
expect(res.body.username).toBe('admin');
});
});
Common Mistakes
- Forgetting to return the promise from async test functions
- Testing with the app listening on a port instead of passing the app instance
- Not setting up and tearing down test database state
- Hardcoding test tokens that expire
- Expecting exact JSON matches when response includes dynamic fields (dates, IDs)
Practice
- Write a GET test that expects status 200 and JSON content type.
- Write a POST test that creates a resource and validates the response.
- Write a DELETE test that verifies resource removal.
- Write a test with authentication headers.
- Challenge: Write a test suite for a file upload endpoint including validation errors.
FAQ
Mini Project
Write a Supertest test suite for a REST API with: CRUD tests for a resource, authentication tests (login, protected routes, invalid token), input validation tests, pagination tests, and file upload test.
What's Next
Next, you will learn about pytest for testing Python APIs with httpx.
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro