How to Mock Express in Jest (with TypeScript)

Mocking libraries like express in Jest can be tricky, especially when working with TypeScript. But with the right setup, you can unit test your Express routes, middleware, and controllers cleanly — without spinning up a real server.

In this article, we’ll walk through how to mock Express in TypeScript using Jest, step by step, with a real-world example.


📦 Prerequisites

Before we start, make sure you have the required packages installed:

npm install express
npm install --save-dev jest ts-jest @types/jest @types/express typescript

Update your jest.config.ts:

export default {
  preset: 'ts-jest',
  testEnvironment: 'node',
};

🎯 Goal: Test That a Route is Registered

Let’s say you have this route file: userRoutes.ts

import { Router, Request, Response } from 'express';

const router = Router();

router.get('/users', (req: Request, res: Response) => {
  res.json({ message: 'List of users' });
});

export default router;

You want to test that GET /users is registered properly — without involving the actual Express implementation.


🧪 Step-by-Step: Mock Express Router in Jest (TypeScript)

✅ 1. Create a Manual Mock for Express

Inside __mocks__/express.ts:

const routerMock = {
  get: jest.fn(),
  post: jest.fn(),
  put: jest.fn(),
  delete: jest.fn(),
};

export const Router = () => routerMock;
export const Request = {};
export const Response = {};

✅ TypeScript tip: jest.mock will automatically pick up the __mocks__ version when the path matches.


✅ 2. Tell Jest to Use the Mock

In your test file, e.g., userRoutes.test.ts:

jest.mock('express');

import express from 'express';
import router from './userRoutes';

describe('userRoutes', () => {
  it('should register GET /users route', () => {
    const mockedRouter = express.Router() as any;

    expect(mockedRouter.get).toHaveBeenCalledWith('/users', expect.any(Function));
  });
});

Important: TypeScript doesn’t automatically infer the mock type, so casting as any is okay here — or you can define a custom mock interface.


🧰 Bonus: Test Route Handlers by Mocking req and res

You can also test the handler itself like this:

import { Request, Response } from 'express';

const handler = (req: Request, res: Response) => {
  res.json({ success: true });
};

test('should return success response', () => {
  const req = {} as Request;
  const res = {
    json: jest.fn(),
  } as unknown as Response;

  handler(req, res);

  expect(res.json).toHaveBeenCalledWith({ success: true });
});

✨ Optional: Create a Typed Express Mock Utility

To avoid repeating boilerplate, create a helper file test-utils/expressMock.ts:

import { Response } from 'express';

export const mockResponse = (): Response => {
  const res = {} as Response;
  res.status = jest.fn().mockReturnThis();
  res.json = jest.fn().mockReturnThis();
  res.send = jest.fn().mockReturnThis();
  return res;
};

Then use it in your tests:

const res = mockResponse();

✅ Summary

Here’s what you learned:

  • How to mock express.Router in TypeScript using a manual Jest mock
  • How to test if a route is registered correctly
  • How to mock req and res to test route handlers or controllers
  • How to make type-safe mocks in TypeScript