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: UnstableDevWorkerbeforeAll(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 completeconst getResponsePromise = worker.fetch(url)// The post request to the same path should receive a response that the text was consumedconst 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 textconst getResponse = await getResponsePromiseexpect(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 completeconst 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 consumedconst 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 textconst getResponse1 = await getResponsePromise1expect(getResponse1.status).toBe(200)const text1 = await getResponse1.text()expect(text1).toBe("Hello World 12345")const getResponse2 = await getResponsePromise2expect(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 completeconst getResponsePromise1 = worker.fetch(url(path))// The post request to the same path should receive a response that the text was consumedconst 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 textconst getResponse1 = await getResponsePromise1expect(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 completeconst getResponsePromise2 = worker.fetch(url(path))// Send a new POST with different textconst 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 textconst getResponse2 = await getResponsePromise2expect(getResponse2.status).toBe(200)const text2 = await getResponse2.text()expect(text2).toBe("Hello World 789")})})})
Find the full code for this example on GitHub.