Use the @cloudflare/vitest-plugin ↗ package to write tests for your Durable Objects. This integration runs your tests inside the Workers runtime, giving you direct access to Durable Object bindings and APIs.
Install Vitest and the Workers Vitest integration as dev dependencies:
npm i -D vitest@^4.1.0 @cloudflare/vitest-pluginpnpm add -D vitest@^4.1.0 @cloudflare/vitest-pluginyarn add -D vitest@^4.1.0 @cloudflare/vitest-pluginThis example tests a simple counter Durable Object with SQLite storage:
import { DurableObject } from "cloudflare:workers";
export class Counter extends DurableObject {
constructor(ctx, env) {
super(ctx, env);
ctx.blockConcurrencyWhile(async () => {
this.ctx.storage.sql.exec(`
CREATE TABLE IF NOT EXISTS counters (
name TEXT PRIMARY KEY,
value INTEGER NOT NULL DEFAULT 0
)
`);
});
}
// In-memory only. This field lives on the instance and is not persisted
// to storage, so it is reset whenever the Durable Object is evicted and
// reconstructed.
cachedHits = 0;
recordHit() {
return ++this.cachedHits;
}
getHits() {
return this.cachedHits;
}
async increment(name = "default") {
this.ctx.storage.sql.exec(
`INSERT INTO counters (name, value) VALUES (?, 1)
ON CONFLICT(name) DO UPDATE SET value = value + 1`,
name,
);
const result = this.ctx.storage.sql
.exec("SELECT value FROM counters WHERE name = ?", name)
.one();
return result.value;
}
async getCount(name = "default") {
const result = this.ctx.storage.sql
.exec("SELECT value FROM counters WHERE name = ?", name)
.toArray();
return result[0]?.value ?? 0;
}
async reset(name