Skip to content

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

Miniflare 2 のテスト環境から移行する

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

Miniflare 2 は、jest-environment-miniflarevitest-environment-miniflare パッケージで、Jest と Vitest 向けのカスタム環境を提供していました。 @cloudflare/vitest-plugin パッケージは、新しい Miniflare と workerd ランタイム を使って、同様の機能を提供します。workerd は Cloudflare Workers を動かしている JavaScript / WebAssembly ランタイムです。workerd を使うと、テストとデプロイ後のコードの挙動のずれを減らせます。詳細は Miniflare 3 の発表 を参照してください。

Workers Vitest integration をインストールする

まず、古い環境をアンインストールし、Vitest plugin をインストールします。Vitest の環境はグローバルスコープしかカスタマイズできません。一方、プラグインは別のランタイムでテストを実行します。この場合、プラグインは Node.js ではなく workerd 内でテストを実行します。

npm uninstall vitest-environment-miniflare
npm install --save-dev vitest@^4.1.0
npm install --save-dev @cloudflare/vitest-plugin

Vitest の設定ファイルを更新する

Workers Vitest integration をインストールしたら、Vitest の設定ファイルを更新し、代わりに cloudflareTest() Vite plugin を使うようにします。以前 environmentOptions に書いていた Miniflare の設定の多くは、cloudflareTest()miniflare オプションへ移せます。対応するオプションは Miniflare の WorkerOptions インターフェイス を、移行の詳細は Miniflare バージョン 2 から 3 への移行ガイド を参照してください。Wrangler ファイルに置いた設定に依存していた場合は、wrangler.configPath も設定します。

+ import { cloudflareTest } from "@cloudflare/vitest-plugin";
+ import { defineConfig } from "vitest/config";

- export default defineWorkersConfig({
-   test: {
-     environment: "miniflare",
-     environmentOptions: { ... },
-   },
- });
+ export default defineConfig({
+   plugins: [
+     cloudflareTest({
+       miniflare: { ... },
+       wrangler: { configPath: "./wrangler.jsonc" },
+     }),
+   ],
+ });

TypeScript の設定ファイルを更新する

TypeScript を使っている場合は、tsconfig.json を更新して、正しいアンビエント types を含めます。

  {
    "compilerOptions": {
      ...,
      "types": [
				...
-       "vitest-environment-miniflare/globals"
+       "@cloudflare/vitest-plugin/types"
      ]
    },
  }

bindings にアクセスする

テストから bindings にアクセスするには、cloudflare:workers モジュールの env ヘルパーを使います。

  import { it } from "vitest";
+ import { env } from "cloudflare:workers";

  it("does something", () => {
-   const env = getMiniflareBindings();
    // ...
  });

TypeScript を使っている場合は、テスト用に env の型を定義する必要があります。セットアップ手順は 型を定義する を参照してください。

ストレージの分離

ストレージの分離は、デフォルトでテストファイル単位です。テストに setupMiniflareIsolatedStorage() を含める必要はなくなりました。

- const describe = setupMiniflareIsolatedStorage();
+ import { describe } from "vitest";

waitUntil() を扱う

new ExecutionContext() コンストラクターと getMiniflareWaitUntil() 関数は、それぞれ createExecutionContext()waitOnExecutionContext() になりました。waitOnExecutionContext() は、waitUntil() したすべての Promise の結果に解決する Promise ではなく、空の Promise<void> を返す点に注意してください。

+ import { createExecutionContext, waitOnExecutionContext } from "cloudflare:test";

  it("does something", () => {
    // ...
-   const ctx = new ExecutionContext();
+   const ctx = createExecutionContext();
    const response = worker.fetch(request, env, ctx);
-   await getMiniflareWaitUntil(ctx);
+   await waitOnExecutionContext(ctx);
  });

外向きリクエストをモックする

getMiniflareFetchMock() 関数は使えなくなりました。外向きリクエストをモックするには、@msw/cloudflare を使います。セットアップ手順は 外向きリクエストをモックする を参照してください。

Durable Object ヘルパーを使う

getMiniflareDurableObjectStorage()getMiniflareDurableObjectState()getMiniflareDurableObjectInstance()runWithMiniflareDurableObjectGates() は、いずれも cloudflare:test モジュールの単一の runInDurableObject() 関数に置き換わりました。runInDurableObject()DurableObjectStub を受け取り、コールバックは Durable Object と対応する DurableObjectState を引数に取ります。これらの関数を 1 つにまとめると API 面が小さくなり、インスタンスへ正しいリクエストコンテキストと ゲーティングの動作 でアクセスできます。詳細は Test APIs のページ を参照してください。

+ import { env } from "cloudflare:workers";
+ import { runInDurableObject } from "cloudflare:test";

  it("does something", async () => {
-   const env = getMiniflareBindings();
    const id = env.OBJECT.newUniqueId();
+   const stub = env.OBJECT.get(id);

-   const storage = await getMiniflareDurableObjectStorage(id);
-   doSomethingWith(storage);
+   await runInDurableObject(stub, async (instance, state) => {
+     doSomethingWith(state.storage);
+   });

-   const state = await getMiniflareDurableObjectState(id);
-   doSomethingWith(state);
+   await runInDurableObject(stub, async (instance, state) => {
+     doSomethingWith(state);
+   });

-   const instance = await getMiniflareDurableObjectInstance(id);
-   await runWithMiniflareDurableObjectGates(state, async () => {
-     doSomethingWith(instance);
-   });
+   await runInDurableObject(stub, async (instance) => {
+     doSomethingWith(instance);
+   });
  });

flushMiniflareDurableObjectAlarms() 関数は、cloudflare:test モジュールの runDurableObjectAlarm() 関数に置き換わりました。runDurableObjectAlarm() は 1 つの DurableObjectStub を受け取り、アラームがスケジュールされて alarm() ハンドラーが実行された場合は true、そうでなければ false に解決する Promise を返します。複数インスタンスのアラームを「フラッシュ」するには、ループ内で runDurableObjectAlarm() を呼び出します。

+ import { env } from "cloudflare:workers";
+ import { runDurableObjectAlarm } from "cloudflare:test";

  it("does something", async () => {
-   const env = getMiniflareBindings();
    const id = env.OBJECT.newUniqueId();
-   await flushMiniflareDurableObjectAlarms([id]);
+   const stub = env.OBJECT.get(id);
+   const ran = await runDurableObjectAlarm(stub);
  });

最後に、getMiniflareDurableObjectIds() 関数は、cloudflare:test モジュールの listDurableObjectIds() 関数に置き換わりました。listDurableObjectIds() は、型を厳密にするため、名前空間の string ではなく DurableObjectNamespace インスタンスを受け取ります。listDurableObjectIds() はストレージの分離に従います。ほかのテストファイルで作成したオブジェクトの ID は返りません。

+ import { env } from "cloudflare:workers";
+ import { listDurableObjectIds } from "cloudflare:test";

  it("does something", async () => {
-   const ids = await getMiniflareDurableObjectIds("OBJECT");
+   const ids = await listDurableObjectIds(env.OBJECT);
  });

役に立ちましたか?