Skip to content

Mock outbound requests

Last updated View as MarkdownAgent setup

Use @msw/cloudflare to mock outbound HTTP and WebSocket requests with @cloudflare/vitest-plugin. The integration supports unit tests that call your Worker's exported handler and integration tests that call exports.default.fetch().

Install dependencies

Install Mock Service Worker (MSW) version 2.14 or later and the Cloudflare integration:

npm i -D msw@^2.14.0 @msw/cloudflare

Create a network mock

Create a shared network mock for your tests:

test/network.jsjs
import { setupNetwork } from "@msw/cloudflare";

export const network = setupNetwork();
test/network.tsts
import { setupNetwork } from "@msw/cloudflare";

export const network = setupNetwork();

In a Vitest setup file, start the mock before tests, reset handlers after each test, and stop it after tests finish:

test/setup.jsjs
import { afterAll, afterEach, beforeAll } from "vitest";
import { network } from "./network";

beforeAll(() => network.enable());
afterEach(() => network.resetHandlers());
afterAll(() => network.disable());
test/setup.tsts
import { afterAll, afterEach, beforeAll } from "vitest";
import { network } from "./network";

beforeAll(() => network.enable());
afterEach(() => network.resetHandlers());
afterAll(() => network.disable());

Add the setup file to the setupFiles array in your Vitest configuration.

Mock an HTTP request

Use network.use() and MSW request handlers to return a response for an outbound request. This example tests a Worker that requests a greeting from an external API:

src/index.jsjs
export default {
	async fetch() {
		return fetch("https://api.example.com/greeting");
	},
};
src/index.tsts
export default {
	async fetch(): Promise<Response> {
		return fetch("https://api.example.com/greeting");
	},
} satisfies ExportedHandler;
test/worker.test.jsjs
import {
	createExecutionContext,
	waitOnExecutionContext,
} from "cloudflare:test";
import { env } from "cloudflare:workers";
import { http, HttpResponse } from "msw";
import { expect, it } from "vitest";
import worker from "../src";
import { network } from "./network";

it("mocks an outbound request", async () => {
	network.use(
		http.get("https://api.example.com/greeting", () => {
			return HttpResponse.json({ message: "Hello" });
		}),
	);

	const ctx = createExecutionContext();
	const response = await worker.fetch(
		new Request("https://example.com"),
		env,
		ctx,
	);
	await waitOnExecutionContext(ctx);
	expect(await response.json()).toEqual({ message: "Hello" });
});
test/worker.test.tsts
import { createExecutionContext, waitOnExecutionContext } from "cloudflare:test";
import { env } from "cloudflare:workers";
import { http, HttpResponse } from "msw";
import { expect, it } from "vitest";
import worker from "../src";
import { network } from "./network";

it("mocks an outbound request", async () => {
	network.use(
		http.get("https://api.example.com/greeting", () => {
			return HttpResponse.json({ message: "Hello" });
		}),
	);

	const ctx = createExecutionContext();
	const response = await worker.fetch(
		new Request("https://example.com"),
		env,
		ctx,
	);
	await waitOnExecutionContext(ctx);
	expect(await response.json()).toEqual({ message: "Hello" });
});

Mock an outbound WebSocket

Use MSW's ws.link() API to mock a WebSocket connection created by your Worker. The request-mocking fixture includes HTTP, exports.default.fetch(), and WebSocket examples.

Was this helpful?