Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Module Amqp Laravel Package

codeception/module-amqp

Codeception module for testing AMQP messaging, usually RabbitMQ, in PHP. Adds helpers to declare queues and exchanges, publish messages, and grab or consume them in tests so you can verify message flows alongside your application code.

View on GitHub
Deep Wiki
Context7

Getting Started

Install the module alongside Codeception itself; it pulls php-amqplib/php-amqplib and works over plain sockets, so no ext-amqp is required:

composer require --dev codeception/module-amqp

Enable it on the suite that exercises code which publishes or consumes messages — usually your functional or a dedicated integration suite, not unit:

# tests/functional.suite.yml
modules:
    enabled:
        - AMQP:
            host: '%AMQP_HOST%'
            port: 5672
            username: '%AMQP_USER%'
            password: '%AMQP_PASS%'
            vhost: '/'
            queues: ['orders.created', 'orders.failed']
            cleanup: true

Read the source first, not the docs — with only a handful of stars there are few blog posts, but src/Codeception/Module/AMQP.php is a single class and short. Pay attention to three things: _initialize() (connection setup and queue declaration), _cleanup() (post-test purging, gated by cleanup), and the public see* / grab* / purge* methods, which are the entire API surface.

First day-one use case: your app has just handled a request/command that should have published an event. Assert it did, without standing up a real consumer:

$I->amOnPage('/checkout');
$I->seeResponseCodeIs(200);
$I->seeQueueSizeIs('orders.created', 1);
$I->seeMessageInQueue('orders.created', ['order_id' => 42]);

That single test replaces a lot of ad-hoc rabbitmqadmin scripting in CI.

Implementation Patterns

Publisher assertions after an HTTP call. This is the bread-and-butter pattern: run the request through your framework module (Laravel, Symfony, Phalcon, etc.), then let AMQP inspect the broker. Because the two modules are independent, ordering matters — put the assertion after the request step, and remember the message may not arrive synchronously.

Seeding a queue before a consumer test. The inverse direction is just as useful. Push a fixture onto the queue with the module, then invoke your consumer class directly in-process (not as a long-running worker) and assert on the domain effect:

$I->purgeQueue('orders.created');
$I->haveMessageInQueue('orders.created', ['order_id' => 42]);
$consumer = new OrderCreatedConsumer($container->get('handler'));
$consumer->consume();
// then assert on DB state / mailer / etc.

Isolate with per-suite queues and a dedicated vhost. Never point this module at a vhost your dev or staging app also writes to. Prefer a test vhost or a test_ prefix injected via %AMQP_QUEUE_PREFIX%, and list every queue you touch in queues: so cleanup: true can purge them.

Lean on _cleanup rather than hand-rolled teardown. If you leave cleanup: true, the module purges configured queues between tests. That is usually enough. Only add explicit $I->purgeQueue(...) calls inside _before() when you have queues the config cannot know about, or when you want a guaranteed empty state at the start rather than the end.

Treat grabMessageFromQueue() as the consumer-side escape hatch. It returns a PhpAmqpLib\Message\AMQPMessage, which lets you assert on properties, content type, headers, and body bytes when the array-subset matcher isn't precise enough. Use it when you need to verify a serialization contract (e.g. that content_type is application/json).

Retry instead of sleep when the publisher is asynchronous. If messages can arrive after the response (queued listeners, deferred dispatch), wrap assertions with Codeception's retry support ($I->retrySeeMessageInQueue(...) with the Retry extension enabled) or a small polling helper in a Helper\Amqp trait. Avoid sleep().

Add a thin helper layer for your conventions. A Helper\Amqp that knows how to decode your envelope (e.g. extract payload from {meta, payload}) keeps test bodies readable and gives you one place to change if the message format evolves.

Gotchas and Tips

  • seeMessageInQueue() is a snapshot, not a wait. It reads the queue at call time. Asynchronous publishers will make this flaky unless you poll; treat a single call as valid only for synchronous publish paths.
  • Array matching is a subset match against the decoded body. Passing ['order_id' => 42] generally succeeds if the body has more keys; passing a string usually compares the raw body. If your app publishes with an envelope, match against the envelope, not the inner payload.
  • cleanup: true only purges queues named in queues:. Dynamically declared queues (e.g. per-tenant or per-test suffixes) will silently accumulate and poison later runs. Either enumerate them or purge explicitly.
  • grabMessageFromQueue() is destructive. It consumes the message. Interleaving grab and dontSeeMessageInQueue will produce confusing results; assert first, grab last.
  • No exchange, binding, or routing-key assertions. The module only sees queues. Verifying that an event was routed via a topic exchange or a dead-letter path requires the rabbitmq-management HTTP API, the CLI, or a real bound consumer.
  • Concurrent consumers steal messages. If a background worker is running against the same test vhost, grabMessageFromQueue() may get nothing. Don't run a worker in the same CI job as the assertions, or give each test its own queue.
  • Suite startup fails if the broker is down. The connection is established during _initialize(), so a missing RabbitMQ turns every test in the suite into an error, not a skip. Guard the suite in CI (health-check the container before running) or wrap the connection in a try/catch in your own module subclass.
  • Credentials belong in env vars, not *.suite.yml. Use the %VAR% placeholder syntax shown above; Codeception resolves these from codeception.yml params or the environment.
  • Version alignment is on you. Match module major versions to Codeception majors (module v2 ↔ Codeception 4, v3 ↔ Codeception 5) and check the php-amqplib constraint against your PHP version; the pinned range is the most common install failure.
  • Extension point is subclassing. There is no event system or plugin hook worth relying on. If you need a haveMessageInQueue() helper, exchange assertions, or JSON-decoding matchers, subclass Codeception\Module\AMQP, add your methods, and enable the subclass in *.suite.yml — that's the supported path.
  • Debug via --debug and tests/_output. Connection failures and PHP warnings are logged there; the module itself is quiet, so a failing seeQueue usually means a config typo (host, port, or vhost) rather than a missing queue.
  • Expect some source-reading. With single-digit stars and no dependent packages, there are essentially no third-party examples. Budget an hour to read the ~400-line module class; it will answer most "does it support X?" questions faster than searching.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
pharaonic/laravel-notification-dependencies
beautinow/translug
dev-brainiac/bot-cloaked
octoberrain/html
octoberrain/extension
octoberrain/exception
octoberrain/contracts
frankyso/ipaymu
3mdikram/worldmoneywords
snowsoft/config
itmosoft/laravel-subscriptions
larva/laravel-ai-qwen
adachsoft/api-version-bundle
cgv/localized-resource
noith/settings
kda/laravel-package
kda/filament-dynamic-navigation
bypersoft/signbox
pairus/product-data
fayne/laravel-filament-cms-core