Skip to content
Cloudflare Docs

Testing with Durable Objects

Write tests for Durable Objects.

import { unstable_dev } from "wrangler";
import type { UnstableDevWorker } from "wrangler";
import { describe, expect, it, beforeAll, afterAll } from "vitest";
describe("Worker", () => {
let worker: UnstableDevWorker;
beforeAll(async () => {
worker = await unstable_dev("src/index.ts", {
experimental: { disableExperimentalWarning: true },
});
});
afterAll(async () => {
await worker.stop();
});
it("should deny request for short paths", async () => {
const cases = {
failures: ["/", "/foo", "/foo/", "/%2F"],
};
for (const path of cases.failures) {
const resp = await worker.fetch(`http://example.com${path}`);
if (resp) {
const text = await resp.text();
expect(text).toMatchInlineSnapshot(
'"path must be at least 5 characters"',
);
}
}
});
describe("durable object", () => {
it("Should send text from a POST to a matching GET", async () => {
const path = "/stuff1";
const url = `http://example.com${path}`;
// The get request should wait for the post request to complete
const getResponsePromise = worker.fetch(url);
// The post request to the same path should receive a response that the text was consumed
const postResponse = await worker.fetch(url, {
method: "POST",
body: "Hello World 12345",
});
expect(postResponse.status).toBe(200);
const postText = await postResponse.text();
expect(postText).toBe("The text was consumed!");
// The get request should now receive the text
const getResponse = await getResponsePromise;
expect(getResponse.status).toBe(200);
const text = await getResponse.text();
expect(text).toBe("Hello World 12345");
});
it("Shouldn't send text from a POST to a different GET", async () => {
const path1 = "/stuff1";
const path2 = "/stuff2";
const url = (p: string) => `http://example.com${p}`;
// The get request should wait for the post request to complete
const getResponsePromise1 = worker.fetch(url(path1));
const getResponsePromise2 = worker.fetch(url(path2));
// The post request to the same path should receive a response that the text was consumed
const postResponse1 = await worker.fetch(url(path1), {
method: "POST",
body: "Hello World 12345",
});
expect(postResponse1.status).toBe(200);
const postText1 = await postResponse1.text();
expect(postText1).toBe("The text was consumed!");
const postResponse2 = await worker.fetch(url(path2), {
method: "POST",
body: "Hello World 789",
});
expect(postResponse2.status).toBe(200);
const postText2 = await postResponse2.text();
expect(postText2).toBe("The text was consumed!");
// The get request should now receive the text
const getResponse1 = await getResponsePromise1;
expect(getResponse1.status).toBe(200);
const text1 = await getResponse1.text();
expect(text1).toBe("Hello World 12345");
const getResponse2 = await getResponsePromise2;
expect(getResponse2.status).toBe(200);
const text2 = await getResponse2.text();
expect(text2).toBe("Hello World 789");
});
it("Should not send the same POST twice", async () => {
const path = "/stuff1";
const url = (p: string) => `http://example.com${p}`;
// The get request should wait for the post request to complete
const getResponsePromise1 = worker.fetch(url(path));
// The post request to the same path should receive a response that the text was consumed
const postResponse1 = await worker.fetch(url(path), {
method: "POST",
body: "Hello World 12345",
});
expect(postResponse1.status).toBe(200);
const postText1 = await postResponse1.text();
expect(postText1).toBe("The text was consumed!");
// The get request should now receive the text
const getResponse1 = await getResponsePromise1;
expect(getResponse1.status).toBe(200);
const text1 = await getResponse1.text();
expect(text1).toBe("Hello World 12345");
// The next get request should wait for the next post request to complete
const getResponsePromise2 = worker.fetch(url(path));
// Send a new POST with different text
const postResponse2 = await worker.fetch(url(path), {
method: "POST",
body: "Hello World 789",
});
expect(postResponse2.status).toBe(200);
const postText2 = await postResponse2.text();
expect(postText2).toBe("The text was consumed!");
// The get request should receive the new text, not the old text
const getResponse2 = await getResponsePromise2;
expect(getResponse2.status).toBe(200);
const text2 = await getResponse2.text();
expect(text2).toBe("Hello World 789");
});
});
});

Find the full code for this example on GitHub.