Fake XHR and server for testing JavaScript applications
—
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Pending
The risk profile of this skill
High-level interface for intercepting and responding to HTTP requests with pattern matching, automatic responses, and request history tracking. The fake server provides a complete testing environment for HTTP-based applications.
Create a new fake server instance with optional configuration.
/**
* @typedef {Object} ServerConfig
* @property {boolean} [autoRespond] - Automatically respond to requests after a delay
* @property {number} [autoRespondAfter] - Delay in milliseconds for auto-response (default: 10)
* @property {boolean} [respondImmediately] - Respond to requests immediately when received
* @property {boolean} [fakeHTTPMethods] - Enable HTTP method override via _method parameter
* @property {function(string): void} [logger] - Custom logging function
* @property {boolean} [unsafeHeadersEnabled] - Allow setting unsafe headers
*/
/**
* Create a new fake server instance
* @param {ServerConfig} [config] - Optional configuration object
* @returns {FakeServer} FakeServer instance
*/
function create(config) {
// Implementation
}Usage Example:
const nise = require("nise");
const server = nise.fakeServer.create({
autoRespond: true,
autoRespondAfter: 100
});Set up responses for specific request patterns.
/**
* @typedef {string|Array|Function} ResponseBody - Response body (string, array, or function)
*/
/**
* Configure response for matching requests
* @param {string|null} method - HTTP method (GET, POST, etc.) or null for any method
* @param {string|RegExp|Function|null} url - URL pattern (string, RegExp, or function) or null for any URL
* @param {ResponseBody} body - Response body (string, array, or function)
* @returns {void}
*/
respondWith(method, url, body) {
// Implementation
}
/**
* Configure response for URL pattern (any method)
* @param {string|RegExp|Function} url - URL pattern
* @param {ResponseBody} body - Response body
* @returns {void}
*/
respondWith(url, body) {
// Implementation
}
/**
* Set default response for all requests
* @param {ResponseBody} body - Response body
* @returns {void}
*/
respondWith(body) {
// Implementation
}Usage Examples:
// Method and URL specific
server.respondWith("GET", "/api/users", [
200,
{ "Content-Type": "application/json" },
JSON.stringify([{ id: 1, name: "Alice" }])
]);
// URL pattern matching with RegExp
server.respondWith("GET", /\/api\/users\/\d+/, [
200,
{ "Content-Type": "application/json" },
JSON.stringify({ id: 1, name: "Alice" })
]);
// Function-based responses
server.respondWith("POST", "/api/users", function(request) {
const userData = JSON.parse(request.requestBody);
return [201, { "Content-Type": "application/json" }, JSON.stringify({
id: Date.now(),
...userData
})];
});
// Default response
server.respondWith([404, {}, "Not Found"]);Control when and how requests are processed.
/**
* Process all pending requests using configured responses
* @returns {void}
*/
respond() {
// Implementation
}
/**
* Process all requests immediately, bypassing queue
* @returns {void}
*/
respondAll() {
// Implementation
}Usage Example:
// Manual response processing
server.autoRespond = false;
// ... make requests in application code ...
server.respond(); // Process all pending requestsAccess information about requests made to the fake server.
/**
* @typedef {Object} FakeServer - Server properties for request tracking
* @property {XMLHttpRequest[]} requests - Array of all XMLHttpRequest objects
* @property {number} requestCount - Total number of requests received
* @property {boolean} requested - True if any requests have been made
* @property {boolean} requestedOnce - True if exactly one request has been made
* @property {boolean} requestedTwice - True if exactly two requests have been made
* @property {boolean} requestedThrice - True if exactly three requests have been made
* @property {XMLHttpRequest|null} firstRequest - Reference to the first request
* @property {XMLHttpRequest|null} secondRequest - Reference to the second request
* @property {XMLHttpRequest|null} thirdRequest - Reference to the third request
* @property {XMLHttpRequest|null} lastRequest - Reference to the most recent request
*/
/**
* Get request by index
* @param {number} index - Zero-based request index
* @returns {XMLHttpRequest|null} XMLHttpRequest object or null
*/
getRequest(index) {
// Implementation
}Usage Example:
// After making requests
console.log(`Total requests: ${server.requestCount}`);
console.log(`First request URL: ${server.firstRequest && server.firstRequest.url}`);
console.log(`Last request method: ${server.lastRequest && server.lastRequest.method}`);
// Access specific request
const thirdRequest = server.getRequest(2);
if (thirdRequest) {
console.log(`Third request body: ${thirdRequest.requestBody}`);
}Manage server state and cleanup.
/**
* Restore original XMLHttpRequest and clean up
* @returns {void}
*/
restore() {
// Implementation
}
/**
* Reset server state (both behavior and history)
* @returns {void}
*/
reset() {
// Implementation
}
/**
* Clear configured responses and request queue
* @returns {void}
*/
resetBehavior() {
// Implementation
}
/**
* Clear request history and counters
* @returns {void}
*/
resetHistory() {
// Implementation
}Usage Example:
// Clean up after tests
afterEach(() => {
server.reset(); // Clear state for next test
});
after(() => {
server.restore(); // Restore original XMLHttpRequest
});Update server configuration after creation.
/**
* Update server configuration
* @param {Partial<ServerConfig>} config - Configuration options to update
* @returns {void}
*/
configure(config) {
// Implementation
}Usage Example:
// Change configuration dynamically
server.configure({
autoRespond: false,
logger: console.log
});The fake server supports multiple URL matching strategies:
url.test(requestUrl)url(requestUrl) === trueResponse functions receive the request object and can return dynamic responses:
server.respondWith("POST", "/api/echo", function(request) {
// Access request properties
const method = request.method;
const headers = request.requestHeaders;
const body = request.requestBody;
// Return response array
return [200, { "Content-Type": "application/json" }, body];
});When fakeHTTPMethods is enabled, the server checks for _method parameter in POST requests:
server.configure({ fakeHTTPMethods: true });
// POST request with _method=DELETE will be treated as DELETE
server.respondWith("DELETE", "/api/users/1", [204, {}, ""]);