Testing
Test the real JobStore and Worker with deterministic controls.
The better-effect-mq/testing entrypoint is runner-neutral. TestJobStore
wraps the real MemoryJobStore contract and keeps a ClockTest, an
IdGeneratorTest, a store Layer and a recorded observer together. It does not
mutate private state or implement a second Worker.
The following continuation uses the canonical SendEmail descriptor from
Defining Jobs and observes it with TestJobStore; it does
not declare a second test-only Job.
import { Effect } from 'better-effect'
import { ClockTest, IdGeneratorTest } from 'better-effect/standard-services'
import { TestRuntime } from 'better-effect/testing'
import { Result } from 'better-result'
import { TestJobStore } from 'better-effect-mq/testing'
const clock = new ClockTest(Date.UTC(2026, 0, 1))
const ids = IdGeneratorTest.from((index) => `job-${index + 1}`)
const testStore = TestJobStore.make({ clock, ids })
const runtime = await TestRuntime.make(testStore.layer, {
clock,
idGenerator: ids
})
try {
const id = await runtime.run(() =>
Effect.gen(async function* () {
const value = yield* SendEmail.enqueue({
messageId: 'message-test-1',
recipient: 'ada@example.test'
})
return Result.ok(value)
})
)
if (Result.isError(id)) throw id.error
console.log(await testStore.enqueuedPayloads(SendEmail))
} finally {
await runtime.dispose()
}The harness assertions are oldest-first and readonly:
enqueued, enqueuedPayloads, job, attempts and counts. claim,
settle and release call the public contract with explicit lease tokens.
Named stores use TestJobStore.makeFor(namedToken, options).
The test Job reuses the canonical Zod 4 schema-backed class from
better-effect-schema through Codec.standardSchema, matching the recommended
production boundary. Keep the trusted JSON escape hatch
for intentionally trusted JSON fixtures that do not need runtime validation.
For Worker scenarios, start the real Worker through the test Runtime's public
Layer composition and use ClockTest, a deterministic random source and a zero-delay persisted
backoff. Assert the completed/failed record and attempt ledger after
awaitIdle; advance the test clock for delayed Jobs instead of replacing
Date or using arbitrary sleeps. Also cover Result.err, defects, cleanup
failures, cooperative cancellation, lease expiry and named-store isolation.
The lower-level jobStoreContract exercises adapter conformance. Use it for
store implementations; use TestJobStore for focused application tests.