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;
}