@cfxdevkit/testing
Shared test fixtures and matchers.
Install
pnpm
pnpm add @cfxdevkit/testingScope: Shared test utilities used by every package and project. Test-only.
Responsibilities
- Mock chain client (
createMockClient) - Contract test fixtures via
createDevNodeFixture - Integration helpers wrapping
framework/devnode - Vitest matchers for chain assertions (e.g.,
toBeHexHash,toBeHexAddress) - Utilities for async coordination (
createDeferred,waitFor)
Dev-dependency only.
Planned Mock Inventory
This package is the home for reusable test doubles shared across backend logic packages. Add these before automation, protocol consumers, and MCP tools grow their own local mocks:
MockJobRepository implements JobRepositoryfor deterministic automation job tests.MockExecutionRepository implements ExecutionRepositoryfor execution audit tests.MockKeeperClient implements KeeperClientwith configurable success and error responses.MockPriceSource implements PriceSourcekeyed by token pair.jobFactory(type, overrides?)andstrategyFactory(type, overrides?)for valid automation fixtures.- Vitest matchers such as
toBeHexHash()andtoBeHexAddress().
When these land, add @cfxdevkit/automation as a test-facing dependency or peer so runtime packages can import only the mocks they need.
Sub-paths
| Sub-path | Exports |
|---|---|
. | 8 symbols |
matchers | 2 matchers |
.
export declare const __packageName: "@cfxdevkit/testing";
export interface Deferred<T> {
resolve(value: T | PromiseLike<T>): void;
reject(reason?: any): void;
promise: Promise<T>;
}
export interface MockClientOptions {
/**
* Optional: custom endpoint URL for the mock client.
*/
endpoint?: string;
/**
* Optional: initial state or behavior overrides for the mock.
*/
overrides?: Record<string, any>;
}
export interface DevNodeFixtureOptions {
/**
* Optional: path to a custom configuration file.
*/
configPath?: string;
/**
* Optional: whether to start the node in dev mode.
* @default false
*/
devMode?: boolean;
/**
* Optional: additional environment variables to set.
*/
env?: Record<string, string>;
}
export declare function createDeferred<T>(): Deferred<T>;
export declare function waitFor(
assertion: () => boolean | Promise<boolean>,
options?: {
/**
* Maximum time (in ms) to wait for the assertion to pass.
* @default 5_000
*/
timeout?: number;
/**
* Interval (in ms) between assertion checks.
* @default 50
*/
interval?: number;
}
): Promise<void>;
export declare function createMockClient(
options?: MockClientOptions
): Client;
export declare function createDevNodeFixture(
options?: DevNodeFixtureOptions
): Promise<DevNode>;matchers
export declare function toBeHexHash(received: unknown): {
pass: boolean;
message: () => string;
};
export declare function toBeHexAddress(received: unknown): {
pass: boolean;
message: () => string;
};Usage
import { createDeferred, waitFor, createMockClient } from '@cfxdevkit/testing';
import { toBeHexHash, toBeHexAddress } from '@cfxdevkit/testing/matchers';
expect.extend({ toBeHexHash, toBeHexAddress });
// Async coordination
const deferred = createDeferred<string>();
setTimeout(() => deferred.resolve('done'), 100);
await deferred.promise; // resolves after 100ms
// Mock client
const client = createMockClient({ endpoint: 'http://localhost:8080' });
// DevNode fixture
const fixture = await createDevNodeFixture({
devMode: true,
env: { DEBUG: '1' }
});
// Chain assertions
expect('0x1234...').toBeHexHash();
expect('0xabcdef...').toBeHexAddress();API Reference
See API.md for the full public surface.
Tier
Tier 0 — framework — Must not runtime-import from any higher tier.
API Reference
.
// The package name constant for `@cfxdevkit/testing`.
export declare const __packageName: "@cfxdevkit/testing";
// Represents a deferred value that can be resolved or rejected later.
export interface Deferred<T> {
promise: Promise<T>;
resolve: (value: T | PromiseLike<T>) => void;
reject: (reason?: any) => void;
}
// Configuration options for creating a mock client.
export interface MockClientOptions {
// Optional: custom endpoint URL for the mock client.
endpoint?: string;
// Optional: initial state or behavior overrides for the mock.
overrides?: Record<string, any>;
}
// Configuration options for creating a development node fixture.
export interface DevNodeFixtureOptions {
// Optional: path to a custom configuration file.
configPath?: string;
// Optional: whether to start the node in dev mode.
devMode?: boolean;
// Optional: additional environment variables to set.
env?: Record<string, string>;
}
// Creates and returns a new `Deferred<T>` instance for managing async test flow.
export declare function createDeferred<T>(): Deferred<T>;
// Waits for an assertion to become true (synchronously or asynchronously), with optional timeout and polling interval.
export declare function waitFor(assertion: () => boolean | Promise<boolean>, options?: {
// Maximum time to wait in milliseconds (default: 5000).
timeout?: number;
// Polling interval in milliseconds (default: 50).
interval?: number;
}): Promise<void>;
// Creates and returns a mock `Client` instance for testing purposes, optionally configured via `MockClientOptions`.
export declare function createMockClient(options?: MockClientOptions): Client;
// Creates and returns a `DevNode` fixture (a local development node instance), initialized and ready for testing.
export declare function createDevNodeFixture(options?: DevNodeFixtureOptions): Promise<DevNode>;Usage
import { createDeferred, waitFor, createMockClient } from '@cfxdevkit/testing';
// Example: Using a deferred to control async test flow
const deferred = createDeferred<string>();
setTimeout(() => deferred.resolve('done'), 100);
await deferred.promise; // resolves after 100ms
// Example: Waiting for a condition
await waitFor(() => document.querySelector('#loaded') !== null);
// Example: Creating a mock client
const client = createMockClient({ endpoint: 'http://localhost:8080' });Last updated on