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 3 or later and the Cloudflare integration:

npm i -D msw@^3.0.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?