or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

call-history.mdindex.mdinstance-management.mdrequest-matching.mdresponse-configuration.mdroute-definition.md
tile.json

call-history.mddocs/

Call History & Inspection

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.

Capabilities

Call Verification

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

Call Retrieval

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

Route Completion Verification

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 times

Call History Management

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

Call Log Structure

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

Advanced Filtering

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

Call History Types

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