Flexible response configuration supporting status codes, headers, body content, delays, errors, and dynamic responses. The response system allows complete control over how mocked requests are handled and what data is returned.
Quick response definitions for common scenarios.
type RouteResponseData = Response | number | string | RouteResponseObjectData;Usage Examples:
import fetchMock from "fetch-mock";
// Status code only
fetchMock.get("/api/users", 200);
// String response (defaults to 200)
fetchMock.get("/api/message", "Hello World");
// JSON object response (auto-stringified, defaults to 200)
fetchMock.get("/api/users", [
{ id: 1, name: "Alice" },
{ id: 2, name: "Bob" }
]);
// Pre-constructed Response object
fetchMock.get("/api/data", new Response("custom data", {
status: 201,
headers: { "Content-Type": "text/plain" }
}));Detailed response configuration with full control over all aspects.
interface RouteResponseConfig {
body?: BodyInit | object;
status?: number;
headers?: { [key: string]: string };
throws?: Error;
redirectUrl?: string;
options?: ResponseInit;
}
type RouteResponseObjectData = RouteResponseConfig | object;Usage Examples:
// Complete response configuration
fetchMock.get("/api/users", {
status: 200,
headers: {
"Content-Type": "application/json",
"X-Total-Count": "150"
},
body: [{ id: 1, name: "Alice" }]
});
// Error responses
fetchMock.post("/api/users", {
status: 400,
body: {
error: "Invalid input",
details: ["Name is required", "Email must be valid"]
}
});
// Redirect response
fetchMock.get("/old-endpoint", {
status: 301,
redirectUrl: "/new-endpoint"
});
// Response with additional options
fetchMock.get("/api/stream", {
status: 200,
body: "streaming data",
options: {
statusText: "OK",
headers: new Headers({ "Transfer-Encoding": "chunked" })
}
});Various body content types supported by the Fetch specification.
type BodyInit = string | Blob | ArrayBuffer | TypedArray | DataView | FormData | URLSearchParams | ReadableStream;Usage Examples:
// String body
fetchMock.get("/api/text", { body: "plain text response" });
// JSON object (auto-stringified)
fetchMock.get("/api/json", { body: { message: "success" } });
// Binary data
const buffer = new ArrayBuffer(8);
fetchMock.get("/api/binary", { body: buffer });
// Form data
const form = new FormData();
form.append("name", "Alice");
fetchMock.post("/api/upload", { body: form });
// URL encoded data
const params = new URLSearchParams();
params.append("key", "value");
fetchMock.post("/api/form", { body: params });
// Blob data
const blob = new Blob(["file content"], { type: "text/plain" });
fetchMock.get("/api/file", { body: blob });Function-based responses that generate content based on request details.
type RouteResponseFunction = (callLog: CallLog) => RouteResponseData | RouteResponsePromise;
type RouteResponsePromise = Promise<RouteResponseData>;Usage Examples:
// Dynamic response based on request
fetchMock.get("/api/users/:id", (callLog) => {
const userId = callLog.expressParams?.id;
return {
status: 200,
body: { id: userId, name: `User ${userId}` }
};
});
// Async response function
fetchMock.post("/api/process", async (callLog) => {
const requestBody = JSON.parse(callLog.options.body as string);
// Simulate processing time
await new Promise(resolve => setTimeout(resolve, 100));
return {
status: 202,
body: {
id: Math.random().toString(36),
status: "processing",
input: requestBody
}
};
});
// Response based on headers
fetchMock.get("/api/data", (callLog) => {
const authHeader = callLog.options.headers?.["Authorization"];
if (!authHeader) {
return { status: 401, body: { error: "Unauthorized" } };
}
return { status: 200, body: { data: "secure content" } };
});Simulate network errors and exceptions.
interface RouteResponseConfig {
throws?: Error;
}Usage Examples:
// Throw network error
fetchMock.get("/api/fail", {
throws: new TypeError("Network error")
});
// Throw custom error
fetchMock.get("/api/timeout", {
throws: new Error("Request timeout")
});
// Conditional error throwing
fetchMock.post("/api/validate", (callLog) => {
const body = JSON.parse(callLog.options.body as string);
if (!body.email) {
return { throws: new Error("Email required") };
}
return { status: 200, body: { valid: true } };
});Add artificial delays to simulate network latency.
interface UserRouteConfig {
delay?: number;
}Usage Examples:
// Fixed delay (in milliseconds)
fetchMock.get("/api/slow",
{ body: "delayed response" },
{ delay: 2000 }
);
// Route configuration with delay
fetchMock.route({
url: "/api/data",
method: "GET",
response: { body: [] },
delay: 500
});
// Dynamic delay in response function
fetchMock.get("/api/variable", (callLog) => {
const delay = Math.random() * 1000; // Random delay up to 1 second
return new Promise(resolve => {
setTimeout(() => {
resolve({ body: "variable delay response" });
}, delay);
});
});Make routes wait for other routes to respond first.
interface UserRouteConfig {
waitFor?: RouteName | RouteName[];
}Usage Examples:
// Single dependency
fetchMock.get("/api/auth", { body: { token: "abc123" } }, { name: "auth" });
fetchMock.get("/api/data",
{ body: "secure data" },
{ waitFor: "auth" }
);
// Multiple dependencies
fetchMock.get("/api/config", { body: { theme: "dark" } }, { name: "config" });
fetchMock.get("/api/user", { body: { id: 1 } }, { name: "user" });
fetchMock.get("/api/dashboard",
{ body: "dashboard data" },
{ waitFor: ["config", "user"] }
);Control how many times a route can match.
interface UserRouteConfig {
repeat?: number;
}Usage Examples:
// Route that matches exactly 3 times
fetchMock.get("/api/limited",
{ body: "limited response" },
{ repeat: 3 }
);
// After 3 calls, this route won't match anymore
// Use with fallback for subsequent calls
fetchMock.get("/api/limited", { body: "limited" }, { repeat: 2 });
fetchMock.get("/api/limited", { status: 429 }); // Rate limit after 2 callstype RouteResponse = RouteResponseData | RouteResponsePromise | RouteResponseFunction;
type RouteResponseData = Response | number | string | RouteResponseObjectData;
type RouteResponseObjectData = RouteResponseConfig | object;
type RouteResponsePromise = Promise<RouteResponseData>;
type RouteResponseFunction = (callLog: CallLog) => RouteResponseData | RouteResponsePromise;
interface RouteResponseConfig {
body?: BodyInit | object;
status?: number;
headers?: { [key: string]: string };
throws?: Error;
redirectUrl?: string;
options?: ResponseInit;
}