Connectum API Reference / @connectum/events-amqp / testing
testing ​
Programmable AMQP test double for the @connectum/events-amqp/testing subpath.
FakeAmqpAdapter models the REAL adapter's observable contracts without a broker and without importing amqplib at runtime:
- the typed error taxonomy (
AmqpConnectionError,AmqpTopologyError, …) — inject outcomes per publish via FakeAmqpControl.nextPublish, includingAmqpPublishTimeoutError: the state-UNKNOWN outcome that no real broker (or even Toxiproxy) reproduces deterministically; - the canonical lifecycle union (AmqpLifecycleCallbacks.onLifecycle) INCLUDING the deprecated flat-callback shim — events go through the real adapter's dispatch, so ordering, shim payloads, and exception isolation match the real adapter by construction;
- the consumer-loss events (
consumer-lost,consumer-restored): the broker ending a consumer on a live connection is driven by FakeAmqpControl.loseConsumer / FakeAmqpControl.restoreConsumers; - the state machine:
connect()on a live or recovering adapter throwsalready connectedlike the real one, while an adapter whose recovery gave up accepts a freshconnect()without its old subscriptions; a mid-recoverysubscribe()PARKS and settles with the recovery outcome; the probe-then-recoverconnect()semantics gate onAmqpTopologyErrorexactly like the real probe; - exchange-type routing:
deliver()follows the configuredexchangeType(fanout and headers queues receive every message, the EventBus alone picks handlers) andsubscribe()validates patterns for that type andtopologyModeexactly like the real adapter.
Deliberately NOT modeled (documented divergences):
- declared header bindings:
topologyis not modeled, so a headers fake delivers every message, while the real adapter delivers only what thex-matchbindings declared for the queue intopology.bindingsselect; - timing: there is no backoff — recovery advances only via explicit FakeAmqpControl.completeRecovery / FakeAmqpControl.exhaustRecovery calls, and
reconnecting.delayis always0; a lost consumer comes back through FakeAmqpControl.restoreConsumers (always attempt 1, neverconsumer-restore-failed, the queue name never changes) or silently through FakeAmqpControl.completeRecovery, as connection recovery does; - consumer loss is queue-wide: FakeAmqpControl.loseConsumer takes every live subscription on the queue (a
groupshared by several subscriptions loses all of them), whatever thecause; a realchannel-closedends one subscription's channel only, a deleted queue ends every consumer on it; - a queued topology
failSetupatconnect()WITHOUT fail-fast reportssetup-failed { initial: true }and then connects anyway (the real adapter would keep retrying inside recovery); a NON-topology queued failure atconnect()is consumed silently and the connect proceeds (the real adapter treats it as transient and blocks in recovery); - broker-driven settlement: handler
ack/nackcalls are RECORDED, at most one per delivery per handler (the first wins, as in the real adapter; see the FakeAmqpControl.deliver result) but do not drive redelivery — re-deliver explicitly with a higherattemptto model it. Handler rejections are swallowed exactly like the real consumer (which nacks for redelivery instead of propagating); - the wire-level envelope: FakeAmqpControl.published records the bus-facing call as the adapter received it. Wire fidelity is the real adapter's integration-tested domain. Incoming envelope headers ARE handled with parity:
deliver()honorsx-event-id/x-published-atand strips the internal keys from handler-visible metadata.