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
Enhanced mocks with Express-specific functionality including application mocking, Express request/response extensions, and routing utilities for comprehensive Express application testing.
Create mock Express applications for testing application-level functionality.
/**
* Access Express-specific mock functionality
*/
const express = httpMocks.express;
/**
* Create a mock Express application
* @returns Mock Express application with standard Express methods
*/
function createApplication(): ExpressApplication;
interface ExpressApplication {
// Configuration methods
init(): void;
defaultConfiguration(): void;
set(setting: string, value?: any): any;
get(setting: string): any;
enabled(setting: string): boolean;
disabled(setting: string): boolean;
enable(setting: string): ExpressApplication;
disable(setting: string): ExpressApplication;
// Routing methods (stubs)
use(...args: any[]): ExpressApplication;
route(path: string): any;
param(name: string, handler: Function): ExpressApplication;
all(path: string, ...handlers: Function[]): ExpressApplication;
lazyrouter(): void;
handle(req: any, res: any, next?: Function): void;
// HTTP method handlers (stubs) - includes all HTTP methods
get(path: string, ...handlers: Function[]): ExpressApplication;
post(path: string, ...handlers: Function[]): ExpressApplication;
put(path: string, ...handlers: Function[]): ExpressApplication;
delete(path: string, ...handlers: Function[]): ExpressApplication;
del(path: string, ...handlers: Function[]): ExpressApplication; // deprecated alias
patch(path: string, ...handlers: Function[]): ExpressApplication;
head(path: string, ...handlers: Function[]): ExpressApplication;
options(path: string, ...handlers: Function[]): ExpressApplication;
connect(path: string, ...handlers: Function[]): ExpressApplication;
trace(path: string, ...handlers: Function[]): ExpressApplication;
// Template and other methods
engine(ext: string, fn: Function): ExpressApplication;
render(name: string, options?: any, callback?: Function): void;
listen(...args: any[]): any;
path(): string;
// Application properties
locals: any;
mountpath: string;
settings: any;
request: any;
response: any;
}Usage Examples:
const httpMocks = require('node-mocks-http');
// Create mock Express app
const app = httpMocks.express.createApplication();
// Configure app settings
app.set('view engine', 'ejs');
app.set('port', 3000);
app.enable('trust proxy');
console.log(app.get('view engine')); // 'ejs'
console.log(app.enabled('trust proxy')); // true
// Set locals
app.locals.title = 'My App';
app.locals.settings = { theme: 'dark' };
// Initialize with default Express configuration
app.init();
app.defaultConfiguration();
// Mock routing (methods return app for chaining but don't actually route)
app.use('/api', middlewareFunction);
app.get('/users', userHandler);
app.post('/users', createUserHandler);
// Additional HTTP methods supported
app.put('/users/:id', updateUserHandler);
app.patch('/users/:id', patchUserHandler);
app.delete('/users/:id', deleteUserHandler);
app.del('/users/:id', deleteUserHandler); // deprecated aliasEnhanced request mocking with Express-specific methods and properties.
/**
* Express request prototype with additional methods
*/
const expressRequest = httpMocks.express.request;
interface ExpressRequestExtensions {
// Enhanced header access (handles Referer/Referrer aliasing)
header(name: string): string | undefined;
get(name: string): string | undefined;
// Content negotiation
accepts(...types: string[]): string | false;
acceptsEncodings(...encodings: string[]): string | false;
acceptsEncoding(...encodings: string[]): string | false;
acceptsCharsets(...charsets: string[]): string | false;
acceptsCharset(...charsets: string[]): string | false;
acceptsLanguages(...languages: string[]): string | false;
acceptsLanguage(...languages: string[]): string | false;
// Other Express methods
range(size: number): any;
param(name: string, defaultValue?: any): any;
is(...types: string[]): string | false | null;
// Express properties (getters)
protocol: string;
secure: boolean;
ip: string;
ips: string[];
subdomains: string[];
path: string;
hostname: string;
host: string;
fresh: boolean;
stale: boolean;
xhr: boolean;
}Usage Examples:
// Express request mock with enhanced functionality
const req = httpMocks.createRequest({
headers: {
'Host': 'example.com',
'X-Forwarded-Proto': 'https',
'Accept': 'text/html,application/json',
'Referer': 'https://google.com'
},
ip: '192.168.1.100'
});
// Express-specific properties
console.log(req.protocol); // 'https'
console.log(req.secure); // true
console.log(req.hostname); // 'example.com'
console.log(req.ip); // '192.168.1.100'
// Enhanced header access
console.log(req.get('referrer')); // 'https://google.com' (aliased from Referer)
// Content negotiation
console.log(req.accepts(['json', 'html'])); // 'html' (first match from Accept header)Enhanced response mocking with Express-specific methods.
/**
* Express response prototype with additional methods
*/
const expressResponse = httpMocks.express.response;
// All standard MockResponse methods plus Express-specific enhancements
// (Most Express response functionality is already included in the base MockResponse)Common patterns for testing Express applications with mock objects.
Testing Application Configuration:
const httpMocks = require('node-mocks-http');
function configureApp(app) {
app.set('view engine', 'pug');
app.set('views', './views');
app.enable('trust proxy');
app.disable('x-powered-by');
app.locals.siteName = 'My Website';
app.locals.version = '1.0.0';
}
// Test configuration
const app = httpMocks.express.createApplication();
configureApp(app);
// Verify configuration
console.log(app.get('view engine')); // 'pug'
console.log(app.enabled('trust proxy')); // true
console.log(app.disabled('x-powered-by')); // true
console.log(app.locals.siteName); // 'My Website'Testing Middleware:
function authMiddleware(req, res, next) {
const token = req.get('Authorization');
if (!token) {
return res.status(401).json({ error: 'No token provided' });
}
// Verify token (simplified)
if (token === 'Bearer valid-token') {
req.user = { id: 1, name: 'John Doe' };
next();
} else {
res.status(403).json({ error: 'Invalid token' });
}
}
// Test middleware with valid token
const { req, res } = httpMocks.createMocks({
headers: { 'Authorization': 'Bearer valid-token' }
});
const next = jest.fn();
authMiddleware(req, res, next);
console.log(req.user); // { id: 1, name: 'John Doe' }
console.log(next).toHaveBeenCalled(); // true
// Test middleware with invalid token
const { req: badReq, res: badRes } = httpMocks.createMocks({
headers: { 'Authorization': 'Bearer invalid-token' }
});
authMiddleware(badReq, badRes, next);
console.log(badRes._getStatusCode()); // 403
console.log(badRes._getJSONData()); // { error: 'Invalid token' }Testing Route Handlers:
function getUserHandler(req, res) {
const userId = req.params.id;
// Simulate database lookup
const user = findUserById(userId);
if (!user) {
return res.status(404).json({ error: 'User not found' });
}
// Use content negotiation
res.format({
'application/json': () => res.json(user),
'text/html': () => res.render('user', { user }),
'default': () => res.status(406).send('Not Acceptable')
});
}
// Test JSON response
const { req, res } = httpMocks.createMocks({
params: { id: '123' },
headers: { 'Accept': 'application/json' }
});
getUserHandler(req, res);
console.log(res._getStatusCode()); // 200
console.log(res._isJSON()); // true
console.log(res._getJSONData()); // user object
// Test HTML response
const { req: htmlReq, res: htmlRes } = httpMocks.createMocks({
params: { id: '123' },
headers: { 'Accept': 'text/html' }
});
getUserHandler(htmlReq, htmlRes);
console.log(htmlRes._getRenderView()); // 'user'
console.log(htmlRes._getRenderData()); // { user: ... }Testing Error Handling:
function errorMiddleware(err, req, res, next) {
const isDevelopment = req.app.get('env') === 'development';
const errorResponse = {
message: err.message,
status: err.status || 500
};
if (isDevelopment) {
errorResponse.stack = err.stack;
}
res.status(errorResponse.status).json(errorResponse);
}
// Test error middleware
const app = httpMocks.express.createApplication();
app.set('env', 'development');
const { req, res } = httpMocks.createMocks();
req.app = app; // Link request to app
const error = new Error('Test error');
error.status = 400;
errorMiddleware(error, req, res, () => {});
console.log(res._getStatusCode()); // 400
const errorData = res._getJSONData();
console.log(errorData.message); // 'Test error'
console.log(errorData.stack); // Error stack (because development mode)Properties available when using Express integration:
Application Properties:
Request Properties (additional to base mock):
Response Properties (additional to base mock):
Testing Route Parameters:
function userProfileHandler(req, res) {
const { userId, section } = req.params;
if (!userId || !section) {
return res.status(400).json({ error: 'Missing parameters' });
}
const profile = getUserProfile(userId, section);
res.json(profile);
}
// Test with route parameters
const { req, res } = httpMocks.createMocks({
method: 'GET',
url: '/users/123/profile',
params: { userId: '123', section: 'profile' }
});
userProfileHandler(req, res);
console.log(res._getStatusCode()); // 200
console.log(res._getJSONData()); // profile dataTesting Query Parameters:
function searchHandler(req, res) {
const { q, limit = 10, offset = 0 } = req.query;
if (!q) {
return res.status(400).json({ error: 'Query parameter required' });
}
const results = searchDatabase(q, parseInt(limit), parseInt(offset));
res.json({ results, total: results.length });
}
// Test with query parameters
const { req, res } = httpMocks.createMocks({
method: 'GET',
url: '/search?q=node&limit=5',
query: { q: 'node', limit: '5' }
});
searchHandler(req, res);
console.log(res._getJSONData()); // { results: [...], total: 5 }