@makaio/test-utils
Shared test harnesses for bus mocking and SQLite database lifecycle in Vitest suites.
What This Is
Section titled “What This Is”Centralises the two most common test setup patterns across Makaio framework packages:
- Bus harnesses - Type-safe mock bus instances without
as unknown as IMakaioBuscasts scattered across test files - Drizzle harnesses - Temporary SQLite databases with table creation, data clearing, and handler registration lifecycle tied to Vitest hooks
Installation
Section titled “Installation”This is a private workspace package. Add it to a consuming workspace package with the workspace protocol:
{ "devDependencies": { "@makaio/test-utils": "workspace:*" }}Key Exports
Section titled “Key Exports”Root exports are bus and extension-context test helpers only:
createMockBus()— Partial mock for unit tests (request, emit, on, requestOptional, withFilter)createMockGlobalBus(namespace?)— Full mock for adapter/agent tests (adds once, scoped, __onAny, getContext, registerNamespace, getSchema)createMockScopedBus(namespace?)— MockScopedBus<string>for adapter-internal testscreateTestBusInstance()— Real bus instance for integration tests. Payload schema validation applies for namespaces registered in that bus context.makeStubExtensionContext(bus)— Minimal extension context for service and package tests
Root types:
MockBusResult/MockGlobalBusResult/MockScopedBusResult
The Drizzle helpers are intentionally isolated behind a subpath so ordinary bus tests do not import SQLite, Drizzle, or Vitest lifecycle helpers:
createTempDb(name)— Creates a temp SQLite file with foreign keys enabledcreatePluginTestDb(config)— Suite-level DB withclearData(),registerHandlers(), andclose()lifecycle methodscreateDbCleanup(handlerCleanup, close, dbPath)— Composes handler cleanup, database close, and file deleteusePluginStorageTestLifecycle(createTestDbFn)— Registers beforeAll/beforeEach/afterEach/afterAll hooks automatically
Drizzle subpath types:
TestDbContext/TestDbContextWithCleanupPluginTestDbContext/PluginTestDbConfig/PluginStorageTestContext
Basic Usage
Section titled “Basic Usage”import { createMockBus, createTestBusInstance } from '@makaio/test-utils';import { makeStubExtensionContext } from '@makaio/test-utils';import { usePluginStorageTestLifecycle, createPluginTestDb } from '@makaio/test-utils/drizzle-harness';
// Unit test: mock busconst { bus, request } = createMockBus();request.mockResolvedValue({ profile: null });const service = new MyService(bus);expect(request).toHaveBeenCalledWith(expect.anything(), { id: '123' });
const MakaioBus = createTestBusInstance();
// Integration test: real SQLite with managed lifecycleconst ctx = usePluginStorageTestLifecycle(() => createPluginTestDb({ name: 'my-service', schemas: [sql`CREATE TABLE ...`], tables: ['my_table'], registerHandlers: (db) => registerMyHandlers(MakaioBus, db, makeStubExtensionContext(MakaioBus)), }),);
it('stores and retrieves', async () => { await MakaioBus.request(MySubjects.set, { entity: { id: '1', ... } }); const result = await MakaioBus.request(MySubjects.get, { id: '1' }); expect(result.entity).toBeDefined();});makeStubExtensionContext(bus) requires an explicit bus so tests do not hide which bus instance
storage handlers are registered against. The stub fills only the structural context fields needed
by handler registration; it does not wire real services.
Architecture
Section titled “Architecture”@makaio/test-utils is a devDependency for all packages that test storage or bus behaviour. It is never imported at runtime.
The usePluginStorageTestLifecycle helper solves a recurring problem: rapid SQLite client creation/destruction between tests causes Neon/Rust panics. The suite-level pattern (create DB once in beforeAll, clear data in beforeEach, register handlers per-test) keeps the client alive across the suite while isolating handler state.
Part of Makaio Framework