Test APIs
The Workers Vitest integration provides runtime helpers for writing tests in the cloudflare:test module. The cloudflare:test module is provided by the @cloudflare/vitest-pool-workers package, but can only be imported from test files that execute in the Workers runtime.
-
env: import("cloudflare:test").ProvidedEnv-
Exposes the
envobject for use as the second argument passed to ES modules format exported handlers. This provides access to bindings that you have defined in your Vitest configuration file.
import { env } from "cloudflare:test";it("uses binding", async () => {await env.KV_NAMESPACE.put("key", "value");expect(await env.KV_NAMESPACE.get("key")).toBe("value");});To configure the type of this value, use an ambient module type:
declare module "cloudflare:test" {interface ProvidedEnv {KV_NAMESPACE: KVNamespace;}// ...or if you have an existing `Env` type...interface ProvidedEnv extends Env {}}
-
-
SELF: Fetcher-
Service binding to the default export defined in the
mainWorker. Use this to write integration tests against your Worker. ThemainWorker runs in the same isolate/context as tests so any global mocks will apply to it too.
import { SELF } from "cloudflare:test";it("dispatches fetch event", async () => {const response = await SELF.fetch("https://example.com");expect(await response.text()).toMatchInlineSnapshot(...);});
-
-
fetchMock: import("undici").MockAgent-
Declarative interface for mocking outbound
fetch()requests. Deactivated by default and reset before running each test file. Refer toundici'sMockAgentdocumentation ↗ for more information. Note this only mocksfetch()requests for the current test runner Worker. Auxiliary Workers should mockfetch()es using the MiniflarefetchMock/outboundServiceoptions. Refer to Configuration for more information.
import { fetchMock } from "cloudflare:test";import { beforeAll, afterEach, it, expect } from "vitest";beforeAll(() => {// Enable outbound request mocking...fetchMock.activate();// ...and throw errors if an outbound request isn't mockedfetchMock.disableNetConnect();});// Ensure we matched every mock we definedafterEach(() => fetchMock.assertNoPendingInterceptors());it("mocks requests", async () => {// Mock the first request to `https://example.com`fetchMock.get("https://example.com").intercept({ path: "/" }).reply(200, "body");const response = await fetch("https://example.com/");expect(await response.text()).toBe("body");});
-
-
createExecutionContext(): ExecutionContext- Creates an instance of the
contextobject for use as the third argument to ES modules format exported handlers.
- Creates an instance of the
-
waitOnExecutionContext(ctx:ExecutionContext): Promise<void>-
Use this to wait for all Promises passed to
ctx.waitUntil()to settle, before running test assertions on any side effects. Only accepts instances ofExecutionContextreturned bycreateExecutionContext().
import { env, createExecutionContext, waitOnExecutionContext } from "cloudflare:test";import { it, expect } from "vitest";import worker from "./index.mjs";it("calls fetch handler", async () => {const request = new Request("https://example.com");const ctx = createExecutionContext();const response = await worker.fetch(request, env, ctx);await waitOnExecutionContext(ctx);expect(await response.text()).toMatchInlineSnapshot(...);});
-
-
createScheduledController(options?:FetcherScheduledOptions): ScheduledController-
Creates an instance of
ScheduledControllerfor use as the first argument to modules-formatscheduled()exported handlers.
import { env, createScheduledController, createExecutionContext, waitOnExecutionContext } from "cloudflare:test";import { it, expect } from "vitest";import worker from "./index.mjs";it("calls scheduled handler", async () => {const ctrl = createScheduledController({scheduledTime: new Date(1000),cron: "30 * * * *"});const ctx = createExecutionContext();await worker.scheduled(ctrl, env, ctx);await waitOnExecutionContext(ctx);});
-
-
createMessageBatch(queueName:string, messages:ServiceBindingQueueMessage[]): MessageBatch- Creates an instance of
MessageBatchfor use as the first argument to modules-formatqueue()exported handlers.
- Creates an instance of
-
getQueueResult(batch:MessageBatch, ctx:ExecutionContext): Promise<FetcherQueueResult>-
Gets the acknowledged/retry state of messages in the
MessageBatch, and waits for allExecutionContext#waitUntil()edPromises to settle. Only accepts instances ofMessageBatchreturned bycreateMessageBatch(), and instances ofExecutionContextreturned bycreateExecutionContext().
import { env, createMessageBatch, createExecutionContext, getQueueResult } from "cloudflare:test";import { it, expect } from "vitest";import worker from "./index.mjs";it("calls queue handler", async () => {const batch = createMessageBatch("my-queue", [{id: "message-1",timestamp: new Date(1000),body: "body-1"}]);const ctx = createExecutionContext();await worker.queue(batch, env, ctx);const result = await getQueueResult(batch, ctx);expect(result.ackAll).toBe(false);expect(result.retryBatch).toMatchObject({ retry: false });expect(result.explicitAcks).toStrictEqual(["message-1"]);expect(result.retryMessages).toStrictEqual([]);});
-
-
runInDurableObject<O extends DurableObject, R>(stub:DurableObjectStub, callback:(instance: O, state: DurableObjectState) => R | Promise<R>): Promise<R>-
Runs the provided
callbackinside the Durable Object that corresponds to the providedstub.
This temporarily replaces your Durable Object's
fetch()handler withcallback, then sends a request to it, returning the result. This can be used to call/spy-on Durable Object methods or seed/get persisted data. Note this can only be used withstubs pointing to Durable Objects defined in themainWorker.
export class Counter {constructor(readonly state: DurableObjectState) {}async fetch(request: Request): Promise<Response> {let count = (await this.state.storage.get<number>("count")) ?? 0;void this.state.storage.put("count", ++count);return new Response(count.toString());}}import { env, runInDurableObject } from "cloudflare:test";import { it, expect } from "vitest";import { Counter } from "./index.ts";it("increments count", async () => {const id = env.COUNTER.newUniqueId();const stub = env.COUNTER.get(id);let response = await stub.fetch("https://example.com");expect(await response.text()).toBe("1");response = await runInDurableObject(stub, async (instance: Counter, state) => {expect(instance).toBeInstanceOf(Counter);expect(await state.storage.get<number>("count")).toBe(1);const request = new Request("https://example.com");return instance.fetch(request);});expect(await response.text()).toBe("2");});
-
-
runDurableObjectAlarm(stub:DurableObjectStub): Promise<boolean>- Immediately runs and removes the Durable Object pointed to by
stub's alarm if one is scheduled. Returnstrueif an alarm ran, andfalseotherwise. Note this can only be used withstubs pointing to Durable Objects defined in themainWorker.
- Immediately runs and removes the Durable Object pointed to by
-
listDurableObjectIds(namespace:DurableObjectNamespace): Promise<DurableObjectId[]>-
Gets the IDs of all objects that have been created in the
namespace. RespectsisolatedStorageif enabled, meaning objects created in a different test will not be returned.
import { env, listDurableObjectIds } from "cloudflare:test";import { it, expect } from "vitest";it("increments count", async () => {const id = env.COUNTER.newUniqueId();const stub = env.COUNTER.get(id);const response = await stub.fetch("https://example.com");expect(await response.text()).toBe("1");const ids = await listDurableObjectIds(env.COUNTER);expect(ids.length).toBe(1);expect(ids[0].equals(id)).toBe(true);});
-
-
applyD1Migrations(db:D1Database, migrations:D1Migration[], migrationTableName?:string): Promise<void>- Applies all un-applied D1 migrations stored in the
migrationsarray to databasedb, recording migrations state in themigrationsTableNametable.migrationsTableNamedefaults tod1_migrations. Call thereadD1Migrations()function from the@cloudflare/vitest-pool-workers/configpackage inside Node.js to get themigrationsarray. Refer to the D1 recipe ↗ for an example project using migrations.
- Applies all un-applied D1 migrations stored in the
Was this helpful?
- Resources
- API
- New to Cloudflare?
- Directory
- Sponsorships
- Open Source
- Support
- Help Center
- System Status
- Compliance
- GDPR
- Company
- cloudflare.com
- Our team
- Careers
- © 2025 Cloudflare, Inc.
- Privacy Policy
- Terms of Use
- Report Security Issues
- Trademark