How to Test Routes in Express: Simple Guide with Examples
To test routes in
express, use a testing library like supertest to simulate HTTP requests to your app's endpoints. Combine it with a test runner like Jest to write assertions on the responses and ensure your routes behave as expected.Syntax
Testing Express routes typically involves importing your Express app and using supertest to send HTTP requests. You then use assertions to check the response status, headers, and body.
Key parts:
request(app): Wraps your Express app for testing..get('/path'): Sends a GET request to the specified route..expect(statusCode): Checks the HTTP status code..expect('Content-Type', /json/): Checks response headers..then(response => { ... }): Access the response body for further checks.
javascript
import request from 'supertest'; import app from './app'; test('GET /route returns 200', async () => { await request(app) .get('/route') .expect(200) .expect('Content-Type', /json/) .then(response => { expect(response.body).toEqual({ key: 'value' }); }); });
Example
This example shows a simple Express app with one route and a test that checks if the route returns the expected JSON and status code.
javascript
import express from 'express'; import request from 'supertest'; // Create Express app const app = express(); // Define a route app.get('/hello', (req, res) => { res.json({ message: 'Hello, world!' }); }); // Export app for testing export default app; // Test suite describe('GET /hello route', () => { it('should respond with JSON and status 200', async () => { const response = await request(app).get('/hello'); expect(response.status).toBe(200); expect(response.headers['content-type']).toMatch(/json/); expect(response.body).toEqual({ message: 'Hello, world!' }); }); });
Output
PASS ./app.test.js
GET /hello route
✓ should respond with JSON and status 200 (20 ms)
Common Pitfalls
Common mistakes when testing Express routes include:
- Not exporting the Express app instance separately, which makes it hard to test.
- Starting the server with
app.listen()inside the app file, causing port conflicts during tests. - Not awaiting asynchronous test calls, leading to false positives or unhandled promise rejections.
- Ignoring response headers like
Content-Type, which can cause tests to pass even if the response format is wrong.
javascript
/* Wrong way: Starting server inside app file */ import express from 'express'; const app = express(); app.get('/test', (req, res) => res.send('ok')); app.listen(3000); // This causes issues in tests export default app; /* Right way: Export app without listen, start server separately */ import express from 'express'; const app = express(); app.get('/test', (req, res) => res.send('ok')); export default app; // Server start in separate file import app from './app'; app.listen(3000);
Quick Reference
Tips for testing Express routes:
- Use
supertestto simulate HTTP requests. - Keep your Express app and server start separate.
- Always await async test calls.
- Check status codes, headers, and response body.
- Use descriptive test names for clarity.
Key Takeaways
Use supertest with your Express app to simulate HTTP requests for testing routes.
Export your Express app without calling app.listen() to avoid port conflicts during tests.
Always await asynchronous test calls to ensure tests run correctly.
Check response status, headers, and body to fully verify route behavior.
Write clear and focused tests for each route to catch issues early.