Function: createTestingClient()
createTestingClient<
T>(doBindingName,doInstanceNameOrId,config?):Textends (...args) =>I?RpcAccessible<I> :T&RpcClientProxy
Defined in: packages/testing/src/create-testing-client.ts:52
Creates a testing-optimized RPC client for Cloudflare Durable Objects.
Environment Requirement: This function can only be used within Cloudflare Workers
test environment (vitest with @cloudflare/vitest-pool-workers). It imports from
cloudflare:test which is only available in that environment.
This is a convenience wrapper around createRpcClient that automatically:
- Imports SELF from cloudflare:test
- Uses HTTP transport by default (fast, simple, no connection overhead)
- Automatically switches to WebSocket when downstream messaging is configured
- Provides RPC access to DO instance internals
Type Parameters
T
T
The DO class constructor (e.g., typeof MyDO) or pre-wrapped with RpcAccessible.
Parameters
doBindingName
string
The DO binding name from wrangler.jsonc (e.g., 'MY_DO')
doInstanceNameOrId
string
The DO instance name or ID
config?
Optional configuration for downstream messaging and connection handling
clientId?
string
Optional client ID for downstream messaging If not provided but onDownstream is set, a random ID will be generated
onClose?
(code, reason) => void | Promise<void>
Handler for WebSocket connection close events
Remarks
Automatically switches transport to 'websocket'.
onDownstream?
(payload) => void | Promise<void>
Handler for downstream messages from the DO
Testing Guidance: For most tests, prefer calling methods and using vi.waitFor()
to check state directly. Only use onDownstream when specifically testing downstream
messaging features or complex cross-DO communication patterns where the callback path
itself needs validation.
Remarks
If provided without clientId, a random clientId will be auto-generated and the WebSocket connection will be tagged with it for routing downstream messages. Automatically switches transport to 'websocket'.
Example
// ❌ Don't do this for simple tests
const messages: any[] = [];
await using client = createTestingClient('MY_DO', 'test', {
onDownstream: (msg) => messages.push(msg)
});
await vi.waitFor(() => expect(messages.length).toBe(1));
// ✅ Do this instead - clearer and more direct
await using client = createTestingClient('MY_DO', 'test');
await vi.waitFor(async () => {
const state = await client.getState();
expect(state.count).toBe(1);
});
// ✅ Use onDownstream for cross-DO communication validation
await using client = createTestingClient('USER_DO', 'user-1', {
onDownstream: (notification) => {
expect(notification.type).toBe('message_received');
}
});
transport?
"websocket" | "http"
Transport type to use. Defaults to 'http'.
- 'http': Fast, simple, no connection overhead (default)
- 'websocket': Persistent connection, required for downstream messaging
Remarks
Automatically switches to 'websocket' when onDownstream or onClose is provided.
Returns
T extends (...args) => I ? RpcAccessible<I> : T & RpcClientProxy
A proxy client that supports both RPC calls and lifecycle management
Remarks
Internally calls createRpcClient with testing-specific defaults. For production use or when you need full configuration control (custom transports, WebSocket connections, custom headers, etc.), use createRpcClient directly.
Both functions return the same underlying RpcClient instance and support 'using' for automatic cleanup. The only difference is the level of configuration abstraction.
For test timeouts, use your test framework's timeout features (e.g., Vitest's test.timeout).
Example
using client = createTestingClient<typeof MyDO>('MY_DO', 'instance-name');
await client.ctx.storage.put('key', 'value');
// For TypeScript, it also supports interfaces or pre-wrapping using `RpcAccessible`
type MyDOType = RpcAccessible<InstanceType<typeof MyDO>>;
using client = createTestingClient<MyDOType>('MY_DO', 'instance-name');
// With downstream messaging
using client = createTestingClient<typeof MyDO>('MY_DO', 'instance-name', {
onDownstream: (payload) => console.log('Received:', payload),
onClose: (code, reason) => console.log('Connection closed')
});
Throws
Will fail to import if used outside vitest-pool-workers environment