How to Use Mocha with Express for Testing APIs
To use
Mocha with Express, write test cases that send HTTP requests to your Express app using a library like supertest. Then run mocha to execute these tests and verify your API behavior.Syntax
Use describe to group tests, it to define individual test cases, and supertest to send HTTP requests to your Express app. Use done callback or return promises to handle async tests.
Example parts:
describe('GET /path', () => { ... }): Group tests for a route.it('should respond with 200', (done) => { ... }): Single test case.request(app).get('/path'): Send GET request to Express app..expect(200, done): Assert HTTP status and finish test.
javascript
const request = require('supertest'); const express = require('express'); const app = express(); app.get('/hello', (req, res) => { res.status(200).send('Hello World'); }); describe('GET /hello', () => { it('responds with Hello World', (done) => { request(app) .get('/hello') .expect(200) .expect('Hello World', done); }); });
Example
This example shows a simple Express app with one route and a Mocha test using supertest to check the response status and body.
javascript
const express = require('express'); const request = require('supertest'); const app = express(); app.get('/greet', (req, res) => { res.status(200).json({ message: 'Hi there!' }); }); describe('GET /greet', () => { it('should return JSON greeting with status 200', async () => { const response = await request(app).get('/greet'); if (response.status !== 200) throw new Error('Status not 200'); if (response.body.message !== 'Hi there!') throw new Error('Wrong message'); }); });
Output
GET /greet
✓ should return JSON greeting with status 200
1 passing (XXms)
Common Pitfalls
Common mistakes include:
- Not exporting or passing the Express app instance to the test, causing
supertestto fail. - Forgetting to handle asynchronous tests properly, leading to tests that never finish or false positives.
- Not installing or importing
supertest, which is needed to simulate HTTP requests. - Running tests without starting the server when using
app.listeninstead of exporting the app.
javascript
/* Wrong: Starting server inside test file causes conflicts and async issues */ const app = require('./app'); app.listen(3000); // Avoid this in tests describe('GET /', () => { it('fails because server is already running', () => { // test code }); }); /* Right: Export app and use supertest without listen */ const app = require('./app'); const request = require('supertest'); describe('GET /', () => { it('works correctly', (done) => { request(app).get('/').expect(200, done); }); });
Quick Reference
Tips for using Mocha with Express:
- Use
supertestto simulate HTTP requests. - Export your Express app without calling
app.listen()for easier testing. - Handle async tests with
donecallback or async/await. - Run tests with
npx mochaor add a test script inpackage.json.
Key Takeaways
Use supertest to send HTTP requests to your Express app in Mocha tests.
Export your Express app without starting the server to simplify testing.
Handle asynchronous tests properly with async/await or done callback.
Avoid starting the server inside test files to prevent conflicts.
Run tests using the mocha command after installing dependencies.