Skip to content

非公式本サイトは非公式の日本語ドキュメントであり、Cloudflare 公式サイトではありません。最新情報はdevelopers.cloudflare.comをご確認ください。

テスト状態を準備する

最終更新 Markdown で表示Agent セットアップ

統合テストでは、実行前にローカルストレージへデータが必要なことがあります。テスト中に呼び出したくない外部サービスに依存することもあります。テストハーネスでこの状態を準備し、そうした依存関係を差し替えます。

設定済みバインディングにアクセスする

worker.getEnv() は、Worker に設定された変数、シークレット、バインディングを返します。server.getWorker() に型を指定 すると、これらの値に型が付きます。返されたストレージバインディングを使い、テストから直接データを投入できます。

const apiWorker = server.getWorker("api-worker");
const env = await apiWorker.getEnv();

await env.USERS.put("123", JSON.stringify({ name: "Ada" }));
const apiWorker = server.getWorker<ApiEnv>("api-worker");
const env = await apiWorker.getEnv();

await env.USERS.put("123", JSON.stringify({ name: "Ada" }));

D1 マイグレーションを適用する

worker.applyD1Migrations(bindingName) を使うと、Wrangler 設定から D1 バインディングのマイグレーション設定を読み取ります。設定済みの migrations_dirmigrations_pattern を使います。これらのオプションがない場合は、設定ファイルからの相対パス migrations ディレクトリにある .sql ファイルを読みます。

ストレージのリセット後に呼び出し、まだ実行していないマイグレーションを適用します。その後、worker.getEnv() でデータベースにアクセスし、必要な行を投入します。

const apiWorker = server.getWorker("api-worker");

beforeEach(async () => {
	await apiWorker.applyD1Migrations("DATABASE");

	const env = await apiWorker.getEnv();
	await env.DATABASE.prepare(
		"INSERT INTO daily_reports (date, user_ids) VALUES (?, ?)",
	)
		.bind("2026-05-29", JSON.stringify(["123", "456"]))
		.run();
});
const apiWorker = server.getWorker<ApiEnv>("api-worker");

beforeEach(async () => {
	await apiWorker.applyD1Migrations("DATABASE");

	const env = await apiWorker.getEnv();
	await env.DATABASE.prepare(
		"INSERT INTO daily_reports (date, user_ids) VALUES (?, ?)",
	)
		.bind("2026-05-29", JSON.stringify(["123", "456"]))
		.run();
});

Durable Object ストレージを準備する

worker.getDurableObjectStorage() で、SQLite バックエンドの Durable Object インスタンスのストレージにアクセスできます。バインディング名またはエクスポートされたクラス名を渡します。その後、名前または ID でインスタンスを選びます。

返されたハンドルは Durable Object 内で SQL を実行します。テスト前にインスタンスへデータを投入したり、Worker 実行後に状態を確認したりできます。

const worker = server.getWorker("api-worker");
const storage = await worker.getDurableObjectStorage("COUNTER", {
	name: "user-123",
});

await storage.exec(
	"INSERT INTO counters (id, value) VALUES (?, ?)",
	"user-123",
	0,
);

await worker.fetch("/counter/user-123");

const rows = await storage.exec(
	"SELECT value FROM counters WHERE id = ?",
	"user-123",
);
expect(rows).toEqual([{ value: 1 }]);
const worker = server.getWorker<ApiEnv>("api-worker");
const storage = await worker.getDurableObjectStorage("COUNTER", {
	name: "user-123",
});

await storage.exec(
	"INSERT INTO counters (id, value) VALUES (?, ?)",
	"user-123",
	0,
);

await worker.fetch("/counter/user-123");

const rows = await storage.exec<{ value: number }>(
	"SELECT value FROM counters WHERE id = ?",
	"user-123",
);
expect(rows).toEqual([{ value: 1 }]);

送信リクエストをモックする

テストハーネスは、Worker からの送信 fetch() リクエストを、Node 環境の globalThis.fetch() 関数経由でプロキシします。これにより、これらのリクエストをインターセプトし、テストで予測可能なレスポンスを返せます。

次は vi.spyOn() で単一リクエストをモックする例です。Mock Service Worker(MSW) を使い、好みに応じてリクエストをインターセプトすることもできます。

import { afterEach, test, vi } from "vitest";

afterEach(() => {
	vi.restoreAllMocks();
});

test("loads a user profile", async ({ expect }) => {
	vi.spyOn(globalThis, "fetch").mockImplementation(async (input, init) => {
		const request = new Request(input, init);

		if (request.url === "http://identity.example.com/profile/123") {
			return Response.json({ id: "123", name: "Ada" });
		}

		throw new Error(`Unexpected request: ${request.method} ${request.url}`);
	});

	const worker = server.getWorker();
	const response = await worker.fetch("/users/123");
	expect(await response.json()).toEqual({ id: "123", name: "Ada" });
});
import { afterEach, test, vi } from "vitest";

afterEach(() => {
	vi.restoreAllMocks();
});

test("loads a user profile", async ({ expect }) => {
	vi.spyOn(globalThis, "fetch").mockImplementation(async (input, init) => {
		const request = new Request(input, init);

		if (request.url === "http://identity.example.com/profile/123") {
			return Response.json({ id: "123", name: "Ada" });
		}

		throw new Error(`Unexpected request: ${request.method} ${request.url}`);
	});

	const worker = server.getWorker();
	const response = await worker.fetch("/users/123");
	expect(await response.json()).toEqual({ id: "123", name: "Ada" });
});

テスト Worker でバインディングをモックする

バインディングの挙動を制御したいときは bindingOverrides を使います。ハーネス内で動くテスト Worker へバインディングをルーティングします。たとえば、テスト Worker で Browser Rendering バインディングを差し替え、ブラウザを起動せずに既知のスクリーンショットを返せます。

テスト Worker は、挙動を設定する JSRPC メソッドも公開できます。worker.getExport() でテストのデフォルトエクスポートにアクセスします。

const server = createTestHarness({
	workers: [
		{
			configPath: "./workers/web/wrangler.jsonc",
			bindingOverrides: { BROWSER: "mock-browser" },
		},
		// The test Worker (mock-browser) that replaces the Browser Rendering binding
		{ configPath: "./workers/mock-browser/wrangler.jsonc" },
	],
});

// Access the test Worker to configure its behavior or assert its state.
const mockBrowser = await server.getWorker("mock-browser").getExport();

// Configure the screenshot to be returned through the overridden binding.
await mockBrowser.setScreenshot([137, 80, 78, 71]);

const response = await server.fetch("/reports/2026-05-29.png");
expect(await response.bytes()).toEqual(Uint8Array.from([137, 80, 78, 71]));
const server = createTestHarness({
	workers: [
		{
			configPath: "./workers/web/wrangler.jsonc",
			bindingOverrides: { BROWSER: "mock-browser" },
		},
		// The test Worker (mock-browser) that replaces the Browser Rendering binding
		{ configPath: "./workers/mock-browser/wrangler.jsonc" },
	],
});

// Access the test Worker to configure its behavior or assert its state.
const mockBrowser = await server
	.getWorker<unknown, typeof import("../workers/mock-browser")>("mock-browser")
	.getExport();

// Configure the screenshot to be returned through the overridden binding.
await mockBrowser.setScreenshot([137, 80, 78, 71]);

const response = await server.fetch("/reports/2026-05-29.png");
expect(await response.bytes()).toEqual(Uint8Array.from([137, 80, 78, 71]));

役に立ちましたか?