Mock http requests made using fetch
—
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Pending
The risk profile of this skill
Complete call history tracking and inspection capabilities for verifying request patterns and debugging. The call history system records every request made to fetch-mock and provides powerful filtering and inspection tools. All call history methods are accessed through the fetchMock.callHistory property.
Check if specific requests were made with flexible filtering options.
/**
* Check if any calls match the specified criteria
* @param filter - Optional filter criteria (route name, matcher, or boolean)
* @param options - Additional matching options
* @returns Boolean indicating if matching calls exist
*/
fetchMock.callHistory.called(filter?: CallHistoryFilter, options?: RouteConfig): boolean;Usage Examples:
import fetchMock from "fetch-mock";
// Set up routes
fetchMock.get("/api/users", { body: [] }, { name: "get-users" });
fetchMock.post("/api/users", { status: 201 }, { name: "create-user" });
// Make some requests
await fetch("/api/users");
await fetch("/api/users", { method: "POST", body: JSON.stringify({ name: "Alice" }) });
// Check if any calls were made
expect(fetchMock.callHistory.called()).toBe(true);
// Check specific route by name
expect(fetchMock.callHistory.called("get-users")).toBe(true);
expect(fetchMock.callHistory.called("create-user")).toBe(true);
// Check matched vs unmatched calls
expect(fetchMock.callHistory.called("matched")).toBe(true);
expect(fetchMock.callHistory.called("unmatched")).toBe(false);
expect(fetchMock.callHistory.called(true)).toBe(true); // Same as "matched"
expect(fetchMock.callHistory.called(false)).toBe(false); // Same as "unmatched"
// Check by URL pattern
expect(fetchMock.callHistory.called("begin:https://api.example.com")).toBe(true);
expect(fetchMock.callHistory.called(/\/api\/users/)).toBe(true);
// Check with additional options
expect(fetchMock.callHistory.called(undefined, { method: "GET" })).toBe(true);
expect(fetchMock.callHistory.called(undefined, { method: "DELETE" })).toBe(false);Get detailed information about calls that match specific criteria.
/**
* Get all calls that match the specified criteria
* @param filter - Optional filter criteria
* @param options - Additional matching options
* @returns Array of matching call logs
*/
fetchMock.callHistory.calls(filter?: CallHistoryFilter, options?: RouteConfig): CallLog[];
/**
* Get the most recent call that matches the specified criteria
* @param filter - Optional filter criteria
* @param options - Additional matching options
* @returns Most recent matching call log or undefined
*/
fetchMock.callHistory.lastCall(filter?: CallHistoryFilter, options?: RouteConfig): CallLog | undefined;Usage Examples:
// Get all calls
const allCalls = fetchMock.callHistory.calls();
console.log(`Total calls made: ${allCalls.length}`);
// Get calls for specific route
const userCalls = fetchMock.callHistory.calls("get-users");
console.log(`GET /api/users called ${userCalls.length} times`);
// Get the last call made
const lastCall = fetchMock.callHistory.lastCall();
console.log(`Last URL called: ${lastCall?.url}`);
// Get calls with specific method
const postCalls = fetchMock.callHistory.calls(undefined, { method: "POST" });
console.log(`POST requests: ${postCalls.length}`);
// Get calls matching URL pattern
const apiCalls = fetchMock.callHistory.calls("begin:https://api.example.com");
// Get unmatched calls (for debugging)
const unmatchedCalls = fetchMock.callHistory.calls("unmatched");
if (unmatchedCalls.length > 0) {
console.log("Unmatched requests:", unmatchedCalls.map(c => c.url));
}Verify that routes have been called the expected number of times.
/**
* Check if routes have been called the expected number of times
* @param routeNames - Optional specific route names to check
* @returns Boolean indicating if all checked routes are complete
*/
fetchMock.callHistory.done(routeNames?: RouteName | RouteName[]): boolean;Usage Examples:
// Set up routes with repeat limits
fetchMock.get("/api/data", { body: "data" }, { name: "get-data", repeat: 2 });
fetchMock.post("/api/submit", { status: 201 }, { name: "submit", repeat: 1 });
// Make some requests
await fetch("/api/data");
await fetch("/api/data");
await fetch("/api/submit");
// Check if all routes are done
expect(fetchMock.callHistory.done()).toBe(true);
// Check specific routes
expect(fetchMock.callHistory.done("get-data")).toBe(true);
expect(fetchMock.callHistory.done(["get-data", "submit"])).toBe(true);
// If a route hasn't been called enough times
fetchMock.get("/api/more", { body: "more" }, { name: "more", repeat: 3 });
await fetch("/api/more");
expect(fetchMock.callHistory.done("more")).toBe(false); // Only called 1/3 timesClear call history and manage recorded data.
/**
* Clear all call history and reset route counters
*/
fetchMock.callHistory.clear(): void;
/**
* Wait for all pending responses to complete
* @param waitForResponseMethods - Also wait for response body methods (.text(), .json(), etc.)
* @returns Promise that resolves when all calls are complete
*/
fetchMock.callHistory.flush(waitForResponseMethods?: boolean): Promise<void>;
/**
* Clear history (also available as instance method for chaining)
* @returns FetchMock instance for chaining
*/
fetchMock.clearHistory(): FetchMock;Usage Examples:
// Clear history between tests
fetchMock.callHistory.clear();
// or use the chainable instance method
fetchMock.clearHistory();
expect(fetchMock.callHistory.calls().length).toBe(0);
// Wait for async responses to complete
fetchMock.get("/api/async", async () => {
await new Promise(resolve => setTimeout(resolve, 100));
return { body: "delayed" };
});
const response = fetch("/api/async");
await fetchMock.callHistory.flush(); // Wait for the delayed response
const result = await response;Detailed information about each request and response.
interface CallLog {
args: unknown[]; // Original fetch arguments
url: string; // Request URL
options: NormalizedRequestOptions; // Request options
request?: Request; // Request object (if used)
signal?: AbortSignal; // Abort signal (if present)
route?: Route; // Matched route
response?: Response; // Generated response
expressParams?: { [x: string]: string }; // Express route parameters
queryParams?: URLSearchParams; // URL query parameters
pendingPromises: Promise<unknown>[]; // Pending response promises
}Usage Examples:
// Examine call details
const calls = fetchMock.callHistory.calls();
calls.forEach(call => {
console.log(`URL: ${call.url}`);
console.log(`Method: ${call.options.method}`);
console.log(`Headers:`, call.options.headers);
if (call.expressParams) {
console.log(`Path params:`, call.expressParams);
}
if (call.queryParams) {
console.log(`Query params:`, call.queryParams.toString());
}
});
// Check specific call details
const lastCall = fetchMock.callHistory.lastCall();
if (lastCall) {
console.log("Request body:", lastCall.options.body);
console.log("Response status:", lastCall.response?.status);
}Complex filtering with multiple criteria.
type CallHistoryFilter = RouteName | 'matched' | 'unmatched' | boolean | RouteMatcher;Usage Examples:
// Filter by route name
const userRoutes = fetchMock.callHistory.calls("user-routes");
// Filter by match status
const matched = fetchMock.callHistory.calls("matched");
const unmatched = fetchMock.callHistory.calls("unmatched");
// Filter by URL pattern
const apiCalls = fetchMock.callHistory.calls("begin:https://api.");
const jsonCalls = fetchMock.callHistory.calls("end:.json");
// Filter by method using options
const postCalls = fetchMock.callHistory.calls(undefined, { method: "POST" });
// Filter by headers
const authCalls = fetchMock.callHistory.calls(undefined, {
headers: { "Authorization": "Bearer" }
});
// Complex filtering with function matcher
const complexCalls = fetchMock.callHistory.calls((callLog) => {
return callLog.url.includes("api") &&
callLog.options.method === "GET" &&
callLog.options.headers?.["Content-Type"]?.includes("json");
});type CallHistoryFilter = RouteName | 'matched' | 'unmatched' | boolean | RouteMatcher;
type RouteName = string;
interface CallLog {
args: unknown[];
url: string;
options: NormalizedRequestOptions;
request?: Request;
signal?: AbortSignal;
route?: Route;
response?: Response;
expressParams?: { [x: string]: string };
queryParams?: URLSearchParams;
pendingPromises: Promise<unknown>[];
}
interface NormalizedRequestOptions extends RequestInit {
method: string;
headers: Headers;
body?: BodyInit;
}