0
0
ExpressHow-ToBeginner · 4 min read

How to Test Authentication in Express: Simple Guide

To test authentication in Express, use a testing library like supertest to simulate HTTP requests and check responses. Write tests that send login credentials and verify protected routes respond correctly with or without valid tokens or sessions.
📐

Syntax

Testing authentication in Express involves sending HTTP requests to your app's endpoints and checking the responses. Use supertest to create requests and Jest or another test runner to assert results.

Key parts:

  • request(app).post('/login'): sends a POST request to login route.
  • .send({ username, password }): sends login data.
  • .expect(statusCode): checks HTTP response code.
  • set('Authorization', 'Bearer token'): adds auth header for protected routes.
javascript
import request from 'supertest';
import app from './app'; // your Express app

describe('Authentication Tests', () => {
  it('logs in user', async () => {
    const response = await request(app)
      .post('/login')
      .send({ username: 'user', password: 'pass' })
      .expect(200);
    expect(response.body.token).toBeDefined();
  });

  it('accesses protected route with token', async () => {
    const login = await request(app)
      .post('/login')
      .send({ username: 'user', password: 'pass' });
    const token = login.body.token;

    await request(app)
      .get('/protected')
      .set('Authorization', `Bearer ${token}`)
      .expect(200);
  });
});
💻

Example

This example shows a simple Express app with a login route that returns a token and a protected route that requires the token. The test logs in, gets the token, then accesses the protected route.

javascript
import express from 'express';
import request from 'supertest';
import jwt from 'jsonwebtoken';

const app = express();
app.use(express.json());

const SECRET = 'secretkey';

// Dummy user data
const user = { id: 1, username: 'user', password: 'pass' };

app.post('/login', (req, res) => {
  const { username, password } = req.body;
  if (username === user.username && password === user.password) {
    const token = jwt.sign({ id: user.id }, SECRET);
    return res.json({ token });
  }
  res.status(401).json({ message: 'Invalid credentials' });
});

app.get('/protected', (req, res) => {
  const authHeader = req.headers['authorization'];
  if (!authHeader) return res.status(401).json({ message: 'No token' });

  const token = authHeader.split(' ')[1];
  try {
    jwt.verify(token, SECRET);
    res.json({ message: 'Protected data' });
  } catch {
    res.status(403).json({ message: 'Invalid token' });
  }
});

// Tests
describe('Auth Test Suite', () => {
  it('should login and get token', async () => {
    const res = await request(app)
      .post('/login')
      .send({ username: 'user', password: 'pass' })
      .expect(200);
    expect(res.body.token).toBeDefined();
  });

  it('should deny access without token', async () => {
    await request(app)
      .get('/protected')
      .expect(401);
  });

  it('should access protected route with valid token', async () => {
    const loginRes = await request(app)
      .post('/login')
      .send({ username: 'user', password: 'pass' });
    const token = loginRes.body.token;

    const protectedRes = await request(app)
      .get('/protected')
      .set('Authorization', `Bearer ${token}`)
      .expect(200);

    expect(protectedRes.body.message).toBe('Protected data');
  });
});
Output
PASS ./auth.test.js Auth Test Suite ✓ should login and get token (XX ms) ✓ should deny access without token (XX ms) ✓ should access protected route with valid token (XX ms)
⚠️

Common Pitfalls

  • Not sending the token in the Authorization header causes 401 errors.
  • Using expired or invalid tokens leads to 403 errors.
  • Forgetting to parse JSON body with express.json() breaks login data reading.
  • Testing without awaiting async calls can cause false positives or errors.

Always check your test waits for responses and sets headers correctly.

javascript
/* Wrong: Missing token header */
await request(app)
  .get('/protected')
  .expect(401);

/* Right: Set Authorization header */
await request(app)
  .get('/protected')
  .set('Authorization', `Bearer ${token}`)
  .expect(200);
📊

Quick Reference

Tips for testing Express authentication:

  • Use supertest to simulate HTTP requests.
  • Send login data with .send() and check for tokens.
  • Include tokens in Authorization headers for protected routes.
  • Check status codes: 200 for success, 401 for missing token, 403 for invalid token.
  • Use async/await to handle asynchronous tests properly.

Key Takeaways

Use supertest to send HTTP requests and check authentication responses in Express.
Always include the token in the Authorization header to access protected routes.
Check for correct status codes: 200 for success, 401 for missing token, 403 for invalid token.
Parse JSON bodies with express.json() middleware to read login data.
Write async tests with await to ensure proper test execution.