miniflare
miniflare copied to clipboard
jest-environment-miniflare unable to find Durable Object for worker with default configuration
Hi! First up thanks for an awesome tool
I'm bumping into an issue where I'm unable to use jest-environment-miniflare
for my worker because it's unable to find the Durable Object class:
FAIL src/worker.test.ts
● Test suite failed to run
DurableObjectError [ERR_CLASS_NOT_FOUND]: Class "Channel" for Durable Object "channel" not found
at DurableObjectsPlugin.reload (node_modules/@miniflare/durable-objects/src/plugin.ts:263:15)
at EventTarget.#runAllReloads (node_modules/@miniflare/core/src/index.ts:667:24)
at EventTarget.#reload (node_modules/@miniflare/core/src/index.ts:810:13)
at async EventTarget.getGlobalScope (node_modules/@miniflare/core/src/index.ts:990:5)
at async MiniflareEnvironment.setup (node_modules/jest-environment-miniflare/src/index.ts:206:27)
I'm able to run my worker using npx wrangler@beta dev --local
and wrangler dev
.
I've also deployed it already without any issues.
My wrangler.toml
:
name = "example"
main = "src/index.ts"
compatibility_date = "2022-05-19"
[durable_objects]
tag = "v1"
bindings = [
{ name = "channel", class_name = "Channel" }
]
[[migrations]]
tag = "v1" # Should be unique for each entry
new_classes = ["Channel"]
And jest.config.ts
:
import type {Config} from 'jest';
export default (): Config => {
return {
"testEnvironment": "miniflare",
};
}
My package.json contains:
....
"jest-environment-miniflare": "^2.6.0",
"miniflare": "^2.6.0",
....
"module": "./dist/worker.mjs"
....
I'm using esbuild with the following settings to build the worker from typescript:
esbuild ./src/index.ts --bundle --platform=browser --target=esnext --format=esm --outfile=./dist/worker.mjs
I'm importing and exporting the Durable Object in my worker from another file that is at the same directory level named channel.ts
(as I mentioned I can run, and deploy this worker with bindings fine).
And I can see the class does indeed end up in the built file ./dist/worker.mjs
:
// src/channel.ts
var Channel = class {
...
Additionally I've tried manually specifying the durable object according to: https://miniflare.dev/testing/jest This has no effect. I've also tried using mounting as specified in the miniflare docs which hasn't worked.
Please let me know, If you can see anything obvious I'm doing wrong.
Hey! 👋 Really glad you've found this tool useful! 🙂
I think the issue here is that Miniflare only partially supports the options added in Wrangler 2. Specifically, Miniflare doesn't support the main
option in wrangler.toml
, so can't find your script containing the Durable Objects.
To fix this, you can explicitly tell Miniflare where the script is in your Jest config using something like:
return {
testEnvironment: "miniflare",
testEnvironmentOptions: {
// Miniflare doesn't yet support the `main` field in `wrangler.toml` so we
// need to explicitly tell it where our built worker is. We also need to
// explicitly mark it as an ES module.
scriptPath: "dist/worker.mjs",
modules: true,
}
};
For a complete example project, see https://github.com/cloudflare/miniflare-typescript-esbuild-jest.
Hope this helps, and let me know if you have any other questions. 👍
I'm running into a similar issue, but this is with getMiniflareBindings()
I have a directory named serverless within a frontend project and I'm trying to run the tests from the outside because the whole project will be deployed on cloudflare pages.
Here is the error I'm running into:
error TS2304: Cannot find name 'getMiniflareBindings'.
my jest.config.ts:
import type { Config } from 'jest'
export default (): Config => {
return {
preset: 'ts-jest',
transform: {
'^.+\\.ts?$': 'ts-jest'
},
testEnvironment: 'miniflare',
testEnvironmentOptions: {
// Miniflare doesn't yet support the `main` field in `wrangler.toml` so we
// need to explicitly tell it where our built worker is. We also need to
// explicitly mark it as an ES module.
scriptPath: 'dist/index.mjs',
modules: true
}
}
}
and my handler.test.ts file:
import worker from '../src/index'
test('handle GET', async () => {
const env = getMiniflareBindings()
const result = await worker.fetch(new Request('/', { method: 'GET' }), env)
expect(result.status).toEqual(200)
const text = await result.text()
expect(text).toEqual('request method: GET')
})
I just figured out I needed to create the globals.d.ts file in the test directory to be able to use the method as a global object
now I'm running into the same issue as @spelexander and even after specifying ./dist/index.mjs
in the jest config it still throws the same error
Hey @da7a90-backup! Really sorry for the delayed response, seems like this issue got buried. 🙁 Is this still an issue for you? If it is, could you share your full logs?
Hi! First up thanks for an awesome tool
I'm bumping into an issue where I'm unable to use
jest-environment-miniflare
for my worker because it's unable to find the Durable Object class:FAIL src/worker.test.ts ● Test suite failed to run DurableObjectError [ERR_CLASS_NOT_FOUND]: Class "Channel" for Durable Object "channel" not found at DurableObjectsPlugin.reload (node_modules/@miniflare/durable-objects/src/plugin.ts:263:15) at EventTarget.#runAllReloads (node_modules/@miniflare/core/src/index.ts:667:24) at EventTarget.#reload (node_modules/@miniflare/core/src/index.ts:810:13) at async EventTarget.getGlobalScope (node_modules/@miniflare/core/src/index.ts:990:5) at async MiniflareEnvironment.setup (node_modules/jest-environment-miniflare/src/index.ts:206:27)
I'm able to run my worker using
npx wrangler@beta dev --local
andwrangler dev
. I've also deployed it already without any issues.My
wrangler.toml
:name = "example" main = "src/index.ts" compatibility_date = "2022-05-19" [durable_objects] tag = "v1" bindings = [ { name = "channel", class_name = "Channel" } ] [[migrations]] tag = "v1" # Should be unique for each entry new_classes = ["Channel"]
And
jest.config.ts
:import type {Config} from 'jest'; export default (): Config => { return { "testEnvironment": "miniflare", }; }
My package.json contains:
.... "jest-environment-miniflare": "^2.6.0", "miniflare": "^2.6.0", .... "module": "./dist/worker.mjs" ....
I'm using esbuild with the following settings to build the worker from typescript:
esbuild ./src/index.ts --bundle --platform=browser --target=esnext --format=esm --outfile=./dist/worker.mjs
I'm importing and exporting the Durable Object in my worker from another file that is at the same directory level named
channel.ts
(as I mentioned I can run, and deploy this worker with bindings fine).And I can see the class does indeed end up in the built file
./dist/worker.mjs
:// src/channel.ts var Channel = class { ...
Additionally I've tried manually specifying the durable object according to: https://miniflare.dev/testing/jest This has no effect. I've also tried using mounting as specified in the miniflare docs which hasn't worked.
Please let me know, If you can see anything obvious I'm doing wrong.
I am encountering a comparable issue with the vitest tool, where the test previously functioned correctly with KVnamespace, but it has ceased working since Durable Objects were implemented. Despite attempting every conceivable workaround for this and similar problems, I have been unable to find a solution thus far.
Hey! 👋 We're planning on revamping the Vitest environment for Miniflare 3 soon, and will be sure to include docs for usage with Durable Objects. I'm going to close this issue as the original issue seems to be solved. 👍