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
andres
to test route handlers or controllers - How to make type-safe mocks in TypeScript