Mock HTTP objects for testing Express, Next.js, and Koa routing functions
—
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Pending
The risk profile of this skill
Convenient functions for creating individual mocks or linked request/response pairs that can interact with each other, with full TypeScript support for different frameworks.
Creates linked request and response objects that can interact with each other, essential for testing functionality that requires both objects.
/**
* Creates linked request and response mocks that can interact
* @param reqOptions - Options for request creation
* @param resOptions - Options for response creation
* @returns Object containing both req and res mocks
*/
function createMocks<T1 extends RequestType = Request, T2 extends ResponseType = Response>(
reqOptions?: RequestOptions,
resOptions?: ResponseOptions
): Mocks<T1, T2>;
interface Mocks<T1 extends RequestType, T2 extends ResponseType> {
req: MockRequest<T1>;
res: MockResponse<T2>;
}Usage Examples:
const httpMocks = require('node-mocks-http');
// Basic linked mocks
const { req, res } = httpMocks.createMocks();
// Linked mocks with configuration
const { req, res } = httpMocks.createMocks({
method: 'POST',
url: '/api/users',
headers: { 'Content-Type': 'application/json' },
body: { name: 'John', email: 'john@example.com' }
}, {
locals: { user: { id: 1 } }
});
// Use in route handler that needs both objects
yourRouteHandler(req, res);
// The response can use the request for content negotiation
res.format({
'text/html': () => res.send('<h1>Hello</h1>'),
'application/json': () => res.json({ message: 'Hello' })
});Full TypeScript integration with generic type parameters for different frameworks.
// Express types (default)
const { req, res } = httpMocks.createMocks<Express.Request, Express.Response>();
// Next.js API routes
const { req, res } = httpMocks.createMocks<NextApiRequest, NextApiResponse>();
// Next.js App Router
const { req, res } = httpMocks.createMocks<NextRequest, NextResponse>();
// Custom types extending base HTTP types
interface CustomRequest extends IncomingMessage {
user?: { id: number; name: string };
}
const { req, res } = httpMocks.createMocks<CustomRequest, ServerResponse>();Usage Examples:
import * as httpMocks from 'node-mocks-http';
import { NextApiRequest, NextApiResponse } from 'next';
// Next.js API route testing
const { req, res } = httpMocks.createMocks<NextApiRequest, NextApiResponse>({
method: 'GET',
query: { id: '123' }
});
// Type-safe access to Next.js specific properties
console.log(req.query.id); // TypeScript knows this is a string | string[]
// Express route testing
import { Request, Response } from 'express';
const { req, res } = httpMocks.createMocks<Request, Response>({
method: 'POST',
body: { data: 'test' },
params: { userId: '456' }
});
// Type-safe Express properties
console.log(req.params.userId); // string
console.log(req.body.data); // any (but known structure)While createMocks() is convenient, you can also create individual mocks when you only need one or the other.
// Import individual creation functions
const { createRequest, createResponse } = require('node-mocks-http');
// Create only request
const request = createRequest({
method: 'GET',
url: '/api/data'
});
// Create only response
const response = createResponse({
locals: { theme: 'dark' }
});When mocks are created together with createMocks(), they can interact in ways that individual mocks cannot.
Content Negotiation:
const { req, res } = httpMocks.createMocks({
headers: { 'Accept': 'application/json' }
});
// The response can access the request's Accept header
res.format({
'text/html': () => res.send('<h1>Data</h1>'),
'application/json': () => res.json({ data: 'value' }),
'default': () => res.status(406).send('Not Acceptable')
});
// Result: JSON response because request accepts JSON
console.log(res._isJSON()); // true
console.log(res._getJSONData()); // { data: 'value' }Session Sharing:
const { req, res } = httpMocks.createMocks({
session: { userId: 123, isAuthenticated: true }
});
// Both request and response can access the same session
console.log(req.session.userId); // 123
// Session can be modified during request processing
req.session.lastAccess = new Date();Detailed configuration options for both request and response creation.
// Request configuration options
const requestOptions = {
method: 'POST', // HTTP method
url: '/api/endpoint', // Request URL
originalUrl: '/api/endpoint', // Original URL before rewriting
baseUrl: '/api', // Base URL portion
path: '/endpoint', // Path portion
params: { id: '123' }, // Route parameters
query: { sort: 'asc' }, // Query string parameters
headers: { // HTTP headers
'Content-Type': 'application/json',
'Authorization': 'Bearer token'
},
body: { data: 'payload' }, // Request body
cookies: { sessionId: 'abc' }, // Cookies
signedCookies: { userId: '123' }, // Signed cookies
session: { authenticated: true }, // Session data
files: { upload: 'file.txt' }, // File uploads
ip: '192.168.1.1', // Client IP
// Any additional custom properties
customProperty: 'value'
};
// Response configuration options
const responseOptions = {
eventEmitter: customEmitter, // Custom event emitter
writableStream: customStream, // Custom writable stream
req: requestObject, // Associated request object
locals: { // Response local variables
user: { id: 1, name: 'John' },
settings: { theme: 'dark' }
}
};
const { req, res } = httpMocks.createMocks(requestOptions, responseOptions);Testing Middleware:
function testMiddleware(req, res, next) {
if (!req.headers.authorization) {
return res.status(401).json({ error: 'Unauthorized' });
}
req.user = { id: 1, name: 'John' };
next();
}
// Test the middleware
const { req, res } = httpMocks.createMocks({
headers: { authorization: 'Bearer token123' }
});
const next = jest.fn();
testMiddleware(req, res, next);
// Verify middleware behavior
console.log(req.user); // { id: 1, name: 'John' }
console.log(next.called); // true
console.log(res._getStatusCode()); // 200 (not 401)Testing Route Handlers:
function userHandler(req, res) {
const userId = req.params.id;
const user = getUserById(userId);
if (!user) {
return res.status(404).json({ error: 'User not found' });
}
res.json(user);
}
// Test the handler
const { req, res } = httpMocks.createMocks({
method: 'GET',
url: '/users/123',
params: { id: '123' }
});
userHandler(req, res);
// Verify handler behavior
console.log(res._getStatusCode()); // 200 or 404
console.log(res._isJSON()); // true
console.log(res._getJSONData()); // user object or errorTesting File Uploads:
const { req, res } = httpMocks.createMocks({
method: 'POST',
url: '/upload',
headers: { 'Content-Type': 'multipart/form-data' },
files: {
document: 'uploaded-file.pdf',
image: 'photo.jpg'
},
body: {
title: 'My Upload',
description: 'File description'
}
});
uploadHandler(req, res);
// Access uploaded files
console.log(req.files.document); // 'uploaded-file.pdf'
console.log(req.body.title); // 'My Upload'Examples of using mock creation with popular testing frameworks:
Jest:
describe('User API', () => {
test('should create user successfully', () => {
const { req, res } = httpMocks.createMocks({
method: 'POST',
body: { name: 'John', email: 'john@example.com' }
});
createUserHandler(req, res);
expect(res._getStatusCode()).toBe(201);
expect(res._isJSON()).toBe(true);
expect(res._getJSONData()).toMatchObject({
id: expect.any(Number),
name: 'John',
email: 'john@example.com'
});
});
});Mocha:
describe('Authentication', () => {
it('should reject unauthenticated requests', () => {
const { req, res } = httpMocks.createMocks({
method: 'GET',
url: '/protected'
});
authMiddleware(req, res, () => {});
expect(res._getStatusCode()).to.equal(401);
expect(res._getJSONData()).to.have.property('error');
});
});