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 ↗.
Was this helpful?
- Resources
- API
- New to Cloudflare?
- Products
- 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