Complete HTTP client mocking system with urllib integration, supporting URL patterns, method filtering, and comprehensive response configuration.
Mock HTTP client requests with flexible URL matching and response configuration.
/**
* Mock HTTP client requests
* @param {string|RegExp} mockUrl - URL pattern to mock
* @param {string|string[]} [mockMethod] - HTTP methods to mock
* @param {MockHttpClientResult} mockResult - Mock response configuration
* @returns {Application} Application instance
*/
app.mockHttpclient(mockUrl, mockMethod, mockResult);
/**
* Mock HTTP client requests (method overload without method parameter)
* @param {string|RegExp} mockUrl - URL pattern to mock
* @param {MockHttpClientResult} mockResult - Mock response configuration
* @returns {Application} Application instance
*/
app.mockHttpclient(mockUrl, mockResult);
type MockHttpClientResult = ResultObject | ResultFunction | string;
interface ResultObject {
/** Response data (string, object, or Buffer) */
data?: string | object | Buffer;
/** HTTP status code */
status?: number;
/** Response headers */
headers?: any;
/** Response delay in milliseconds */
delay?: number;
/** Keep mock persistent across multiple requests */
persist?: boolean;
/** Number of times to repeat the mock */
repeats?: number;
}
type ResultFunction = (url?: string, opts?: any) => ResultObject | string | void;Usage Examples:
// Mock API endpoint with JSON response
app.mockHttpclient('https://api.example.com/users', {
data: [
{ id: 1, name: 'Alice' },
{ id: 2, name: 'Bob' }
],
status: 200,
headers: { 'content-type': 'application/json' }
});
// Mock with string response
app.mockHttpclient('https://api.example.com/status', 'OK');
// Mock with specific HTTP methods
app.mockHttpclient('https://api.example.com/users', ['POST', 'PUT'], {
data: { success: true },
status: 201
});
// Mock with RegExp URL pattern
app.mockHttpclient(/^https:\/\/api\.example\.com\/users\/\d+$/, {
data: { id: 123, name: 'Alice' }
});
// Mock with delay
app.mockHttpclient('https://slow-api.example.com/data', {
data: { result: 'slow response' },
delay: 1000
});Create dynamic responses based on request parameters and URL.
/**
* Result function for dynamic responses
* @param {string} [url] - Requested URL
* @param {Object} [opts] - Request options
* @returns {ResultObject|string|void} Response configuration
*/
type ResultFunction = (url?: string, opts?: any) => ResultObject | string | void;Usage Examples:
// Dynamic response based on URL
app.mockHttpclient(/^https:\/\/api\.example\.com\/users\/(\d+)$/, (url) => {
const userId = url.match(/\/users\/(\d+)$/)[1];
return {
data: { id: parseInt(userId), name: `User ${userId}` },
status: 200
};
});
// Dynamic response based on request options
app.mockHttpclient('https://api.example.com/search', (url, opts) => {
const query = opts.data ? opts.data.q : '';
return {
data: {
query,
results: query ? [`Result for ${query}`] : []
}
};
});
// Conditional responses
app.mockHttpclient('https://api.example.com/auth', (url, opts) => {
const authHeader = opts.headers && opts.headers.authorization;
if (authHeader === 'Bearer valid-token') {
return { data: { authenticated: true }, status: 200 };
} else {
return { data: { error: 'Unauthorized' }, status: 401 };
}
});
// Response based on request method
app.mockHttpclient('https://api.example.com/data', (url, opts) => {
if (opts.method === 'GET') {
return { data: { items: [] } };
} else if (opts.method === 'POST') {
return { data: { id: 123, created: true }, status: 201 };
}
return { status: 405 };
});Configure mocks to persist across multiple requests or repeat a specific number of times.
interface ResultObject {
/** Keep mock persistent across multiple requests */
persist?: boolean;
/** Number of times to repeat the mock */
repeats?: number;
}Usage Examples:
// Persistent mock (stays active for multiple requests)
app.mockHttpclient('https://api.example.com/config', {
data: { version: '1.0', features: ['a', 'b', 'c'] },
persist: true
});
// Limited repeats
app.mockHttpclient('https://api.example.com/limited', {
data: { message: 'Limited availability' },
repeats: 3
});
// Simulate rate limiting
let requestCount = 0;
app.mockHttpclient('https://api.example.com/rate-limited', (url, opts) => {
requestCount++;
if (requestCount <= 5) {
return { data: { success: true } };
} else {
return {
data: { error: 'Rate limit exceeded' },
status: 429,
headers: { 'retry-after': '60' }
};
}
});Direct integration with urllib MockAgent for advanced HTTP mocking scenarios.
/**
* Get mock HTTP agent for urllib
* @returns {MockAgent} MockAgent instance from urllib
*/
app.mockAgent();
/**
* Restore mock HTTP agent
* @returns {Promise<void>} Promise that resolves when agent is restored
*/
app.mockAgentRestore();Usage Examples:
// Get mock agent for advanced configuration
const mockAgent = app.mockAgent();
// Configure agent-level mocking
mockAgent.disableNetConnect();
mockAgent.enableNetConnect('127.0.0.1');
// Create pool for specific origin
const pool = mockAgent.get('https://api.example.com');
pool.intercept({
path: '/users',
method: 'GET'
}).reply(200, { users: [] });
// Restore agent after tests
afterEach(async () => {
await app.mockAgentRestore();
});Comprehensive control over response headers and HTTP status codes.
Usage Examples:
// Custom response headers
app.mockHttpclient('https://api.example.com/data', {
data: { message: 'Success' },
status: 200,
headers: {
'content-type': 'application/json',
'x-rate-limit-remaining': '99',
'x-response-time': '150ms',
'cache-control': 'no-cache'
}
});
// Error responses with specific status codes
app.mockHttpclient('https://api.example.com/protected', {
data: { error: 'Forbidden' },
status: 403,
headers: {
'www-authenticate': 'Bearer realm="api"'
}
});
// Redirect responses
app.mockHttpclient('https://api.example.com/old-endpoint', {
status: 301,
headers: {
'location': 'https://api.example.com/new-endpoint'
}
});
// Content-type specific responses
app.mockHttpclient('https://api.example.com/xml', {
data: '<response><status>ok</status></response>',
headers: { 'content-type': 'application/xml' }
});Mock responses with binary data and Buffer objects.
Usage Examples:
// Mock binary response
app.mockHttpclient('https://api.example.com/image', {
data: Buffer.from('fake-image-data', 'binary'),
headers: { 'content-type': 'image/png' }
});
// Mock file download
app.mockHttpclient('https://api.example.com/download', {
data: Buffer.from('file content here'),
headers: {
'content-type': 'application/octet-stream',
'content-disposition': 'attachment; filename="data.txt"'
}
});
// Mock with base64 data
const imageBuffer = Buffer.from('iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mP8/5+hHgAHggJ/PchI7wAAAABJRU5ErkJggg==', 'base64');
app.mockHttpclient('https://api.example.com/pixel', {
data: imageBuffer,
headers: { 'content-type': 'image/png' }
});Advanced request matching with URL patterns, method filtering, and header inspection.
Usage Examples:
// Match specific query parameters
app.mockHttpclient('https://api.example.com/search', (url, opts) => {
const urlObj = new URL(url);
const page = urlObj.searchParams.get('page') || '1';
const limit = urlObj.searchParams.get('limit') || '10';
return {
data: {
page: parseInt(page),
limit: parseInt(limit),
results: [`Item ${page}-1`, `Item ${page}-2`]
}
};
});
// Method-specific responses
app.mockHttpclient('https://api.example.com/resource', 'GET', {
data: { id: 1, name: 'Resource' }
});
app.mockHttpclient('https://api.example.com/resource', 'POST', {
data: { id: 2, name: 'New Resource' },
status: 201
});
// Multiple method matching
app.mockHttpclient('https://api.example.com/flexible', ['GET', 'HEAD'], {
data: { available: true }
});
// Header-based responses
app.mockHttpclient('https://api.example.com/versioned', (url, opts) => {
const version = opts.headers && opts.headers['api-version'];
if (version === 'v2') {
return { data: { version: 2, features: ['new', 'improved'] } };
} else {
return { data: { version: 1, features: ['basic'] } };
}
});Support for legacy method names and backward compatibility.
/**
* Legacy method name for mockHttpclient (deprecated)
* @deprecated Use app.mockHttpclient instead
*/
app.mockUrllib(...args);Usage Examples:
// Legacy method (still supported but deprecated)
app.mockUrllib('https://api.example.com/legacy', {
data: { deprecated: true }
});
// Equivalent to: app.mockHttpclient('https://api.example.com/legacy', { data: { deprecated: true } })