Testing with Jest and Supertest
Test Node.js apps with Jest. Write unit tests and API tests.
Testing with Jest and Supertest
Why Test?
- Catch bugs before production - Refactor with confidence - Document how code works - Prevent regressions
Setup
```bash npm install --save-dev jest supertest ```
```json { "scripts": { "test": "jest" }, "jest": { "testEnvironment": "node" } } ```
Unit Tests
```javascript // utils.js function add(a, b) { return a + b; }
function isValidEmail(email) { return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email); }
module.exports = { add, isValidEmail }; ```
```javascript // utils.test.js const { add, isValidEmail } = require('./utils');
describe('Math utilities', () => { test('adds two numbers', () => { expect(add(2, 3)).toBe(5); expect(add(-1, 1)).toBe(0); }); });
describe('Email validation', () => { test('validates correct email', () => { expect(isValidEmail('test@example.com')).toBe(true); }); test('rejects invalid email', () => { expect(isValidEmail('invalid')).toBe(false); }); }); ```
API Testing
```javascript // app.js const express = require('express'); const app = express();
app.use(express.json());
app.get('/api/users', (req, res) => { res.json([{ id: 1, name: 'John' }]); });
app.post('/api/users', (req, res) => { res.status(201).json({ id: 2, ...req.body }); });
module.exports = app; ```
```javascript // app.test.js const request = require('supertest'); const app = require('./app');
describe('GET /api/users', () => { test('returns list of users', async () => { const response = await request(app) .get('/api/users') .expect(200) .expect('Content-Type', /json/); expect(response.body).toHaveLength(1); expect(response.body[0]).toHaveProperty('name', 'John'); }); });
describe('POST /api/users', () => { test('creates new user', async () => { const newUser = { name: 'Jane', email: 'jane@example.com' }; const response = await request(app) .post('/api/users') .send(newUser) .expect(201); expect(response.body).toMatchObject(newUser); expect(response.body).toHaveProperty('id'); }); }); ```
Mocking
```javascript const User = require('./models/User');
jest.mock('./models/User');
describe('getUser', () => { test('returns user by id', async () => { const mockUser = { id: 1, name: 'John' }; User.findById.mockResolvedValue(mockUser); const user = await getUser(1); expect(User.findById).toHaveBeenCalledWith(1); expect(user).toEqual(mockUser); }); }); ```
Key Takeaway
Write unit tests for functions, API tests for endpoints. Mock external dependencies. Use beforeEach for test isolation. Aim for 80% code coverage. Run tests in CI/CD.