Skip to content

Commit

Permalink
Feat: allow access to the Durable Object's instance from inside a test (
Browse files Browse the repository at this point in the history
#385)

* feat: added `getMiniflareDurableObjectInstance()` to test environments

This allows access to the Durable Object instance for direct manipulation and testing

* Update durableobjects.module.spec.js

Co-authored-by: MrBBot <bcoll@cloudflare.com>
  • Loading branch information
cdrx and mrbbot authored Dec 22, 2022
1 parent b24707a commit c2bcc74
Show file tree
Hide file tree
Showing 4 changed files with 49 additions and 1 deletion.
9 changes: 9 additions & 0 deletions packages/durable-objects/src/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import {
import { AlarmStore } from "./alarms";
import { DurableObjectError } from "./error";
import {
DurableObject,
DurableObjectConstructor,
DurableObjectFactory,
DurableObjectId,
Expand Down Expand Up @@ -207,6 +208,14 @@ export class DurableObjectsPlugin
return state;
}

async getInstance(
storage: StorageFactory,
id: DurableObjectId
): Promise<DurableObject> {
const state = await this.getObject(storage, id);
return state[kInstance] as DurableObject;
}

getNamespace(
storage: StorageFactory,
objectName: string
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { jest } from "@jest/globals";
import { DurableObjectId } from "@miniflare/durable-objects";

beforeAll(async () => {
Expand Down Expand Up @@ -67,3 +68,16 @@ test("Durable Objects list", async () => {
new DurableObjectId("TEST_OBJECT", id2.toString())
);
});

test("Access to Durable Object instance", async () => {
const env = getMiniflareBindings();
const id = env.TEST_OBJECT.idFromName("test");
const stub = env.TEST_OBJECT.get(id);
const instance = await getMiniflareDurableObjectInstance(id);
const fetch = jest.spyOn(instance, "fetch");

await stub.fetch(new Request("https://object/"));

expect(instance.constructor.name).toBe("TestObject");
expect(fetch).toHaveBeenCalled();
});
12 changes: 12 additions & 0 deletions packages/shared-test-environment/src/globals.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {
kWaitUntil,
} from "@miniflare/core";
import {
DurableObject,
DurableObjectId,
DurableObjectState,
DurableObjectStorage,
Expand Down Expand Up @@ -32,6 +33,9 @@ declare global {
function getMiniflareDurableObjectState(
id: DurableObjectId
): Promise<DurableObjectState>;
function getMiniflareDurableObjectInstance(
id: DurableObjectId
): Promise<DurableObject>;
function runWithMiniflareDurableObjectGates<T>(
state: DurableObjectState,
closure: () => Awaitable<T>
Expand All @@ -56,6 +60,9 @@ export interface MiniflareEnvironmentUtilities {
getMiniflareDurableObjectState(
id: DurableObjectId
): Promise<DurableObjectState>;
getMiniflareDurableObjectInstance(
id: DurableObjectId
): Promise<DurableObject>;
runWithMiniflareDurableObjectGates<T>(
state: DurableObjectState,
closure: () => Awaitable<T>
Expand Down Expand Up @@ -91,6 +98,11 @@ export async function createMiniflareEnvironmentUtilities(
const storage = plugin.getStorage(factory, id);
return new DurableObjectState(id, storage);
},
async getMiniflareDurableObjectInstance(id: DurableObjectId) {
const plugin = (await mf.getPlugins()).DurableObjectsPlugin;
const factory = mf.getPluginStorage("DurableObjectsPlugin");
return await plugin.getInstance(factory, id);
},
runWithMiniflareDurableObjectGates<T>(
state: DurableObjectState,
closure: () => Awaitable<T>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { DurableObjectId } from "@miniflare/durable-objects";
import { beforeAll, expect, test } from "vitest";
import { beforeAll, expect, test, vi } from "vitest";
setupMiniflareIsolatedStorage();

beforeAll(async () => {
Expand Down Expand Up @@ -69,3 +69,16 @@ test("Durable Objects list", async () => {
new DurableObjectId("TEST_OBJECT", id2.toString())
);
});

test("Access to Durable Object instance", async () => {
const env = getMiniflareBindings();
const id = env.TEST_OBJECT.idFromName("test");
const stub = env.TEST_OBJECT.get(id);
const instance = await getMiniflareDurableObjectInstance(id);
const fetch = vi.spyOn(instance, "fetch");

await stub.fetch(new Request("https://object/"));

expect(instance.constructor.name).toBe("TestObject");
expect(fetch).toHaveBeenCalled();
});

0 comments on commit c2bcc74

Please sign in to comment.