Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat: add getMiniflareDurableObjectState function for instantiating DurableObjectState #157

Closed
jorroll opened this issue Jan 19, 2022 · 3 comments
Labels
enhancement New feature or request
Milestone

Comments

@jorroll
Copy link

jorroll commented Jan 19, 2022

At the moment, miniflare supports testing durable object stubs. However, I'd like to instantiate a durable object class and unit test the non-fetch() methods.

At the moment, this is accomplishable but could be more ergonomic. After looking at the miniflare source, I was able to put together the following:

import { DurableObjectState } from '@miniflare/durable-objects';
import { Campaign } from '../src/campaign'; // assume this is a class that implements DurableObject

const env = getMiniflareBindings();
const id = env.CAMPAIGN.newUniqueId();

describe('Campaign', () => {
  let storage: DurableObjectStorage;
  let campaign: Campaign;

  beforeAll(async () => {
    storage = await getMiniflareDurableObjectStorage(id);
  });

  beforeEach(() => {
    campaign = new Campaign(new DurableObjectState(id as any, storage as any), env);
  });

  test('getPeople', async () => {
    expect(await campaign.getPeople()).toBe(0);
    storage.put('totalPeople', 2);
    expect(await campaign.getPeople()).toBe(2);
  });
});

Notice the need to cast to any in new DurableObjectState(id as any, storage as any) (because the DurableObjectId returned from DurableObjectNamespace#newUniqueId() is not the same DurableObjectId typescript type that DurableObjectState expects. Also note that I had to look in the miniflare source to figure out how to instantiate new DurableObjectState().

An improvement would be exposing a getMiniflareDurableObjectState() function like the following:

function getMiniflareDurableObjectState(
  id: DurableObjectId,
): Promise<DurableObjectState>;

function getMiniflareDurableObjectState(
  id: DurableObjectId,
  storage: DurableObjectStorage,
): DurableObjectState;

function getMiniflareDurableObjectState(
  id: DurableObjectId,
  storage?: DurableObjectStorage,
) {
  if (!storage) {
    return getMiniflareDurableObjectStorage(id).then(
      (s) => new DurableObjectState(id as any, s as any),
    );
  }

  return new DurableObjectState(id as any, storage as any);
}

Usage like

import { DurableObjectState } from '@miniflare/durable-objects';
import { Campaign } from '../src/campaign'; // assume this is a class that implements DurableObject

const env = getMiniflareBindings();
const id = env.CAMPAIGN.newUniqueId();

describe('Campaign', () => {
  let storage: DurableObjectStorage;
  let campaign: Campaign;

  beforeAll(async () => {
    storage = await getMiniflareDurableObjectStorage(id);
  });

  beforeEach(async () => {
    campaign = new Campaign(getMiniflareDurableObjectState(id, storage), env);
    // or
    campaign = new Campaign(await getMiniflareDurableObjectState(id), env);
  });
});
@mrbbot
Copy link
Contributor

mrbbot commented Jan 27, 2022

Hey! 👋 I agree, this isn't pretty and should definitely be easier. We'll try sort something out for the next version... 👍

@jorroll
Copy link
Author

jorroll commented Feb 22, 2022

Note: while previously I was able to create my own getMiniflareDurableObjectState() function to test non-fetch methods, at some point in the past month this appears to have been broken. See issue #184. It's unclear what has caused this regression and I haven't actually been able to recreate a "working" getMiniflareDurableObjectState()--even when using previous versions of the miniflare library.

Edit:
I've confirmed that this is a regression.

@mrbbot mrbbot added this to the 2.4.0 milestone Mar 8, 2022
@mrbbot mrbbot modified the milestones: 2.4.0, 2.5.0 Apr 2, 2022
@mrbbot mrbbot modified the milestones: 2.5.0, 2.6.0 May 27, 2022
@mrbbot mrbbot modified the milestones: 2.6.0, 2.7.0 Jul 9, 2022
@mrbbot mrbbot modified the milestones: 2.7.0, 2.8.0 Aug 19, 2022
@mrbbot mrbbot modified the milestones: 2.8.0, 2.9.0 Sep 7, 2022
@mrbbot mrbbot closed this as completed in cdaa62b Sep 12, 2022
@mrbbot
Copy link
Contributor

mrbbot commented Sep 17, 2022

Hey! 👋 Miniflare 2.9.0 has just been released, which implements this change. You can find the full changelog here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants