Seems difficult and there isn't much documentation around this (I'm using FirendsOfBehat Symfony extension). I want to test whether Transport
carries any events by using get()
method but I'm not getting any results. It feels like its not routing the correct Bus.
declare(strict_types=1);
namespace App\Features\BehatContext;
class MessengerContext implements Context
{
/**
* @var TransportInterface
*/
private $transport;
/**
* MessengerContext constructor.
*
* @param TransportInterface $transport ??? Is this ok
*/
public function __construct(TransportInterface $transport)
{
// Symfony\Component\Messenger\Transport\InMemoryTransport
$this->transport = $transport;
}
/**
* THIS IS WHAT DOESN'T WORK
* @Given /^(\d+) Events? "([^"]*)" is dispatched$/
*/
public function eventAEventIsDispatched()
{
$eventsDispatched = $this->transport->get();
Assert::assertTrue(count($eventsDispatched));
}
}
My packages/messenger.yaml
configuration:
framework:
messenger:
default_bus: event.bus
buses:
command.bus:
middleware:
- validation
event.bus:
default_middleware: allow_no_handlers
transports:
sync: 'sync://'
event: 'in-memory:///'
routing:
'App\AddMagazine': sync
'App\MagazineAdded': event
'App\EventAdapter': event
This is the class that dispatches my events
declare(strict_types=1);
namespace App\Event\Dispatcher;
class SymfonyEventDispatcher implements ApplicationDomainDispatcherInterface
{
private $messageBus;
/**
* SymfonyEventDispatcher constructor.
*
* @param MessageBusInterface $sfDispatcher
*/
public function __construct(MessageBusInterface $eventBus)
{
// messageBus is Symfony\Component\Messenger\TraceableMessageBus
$this->messageBus = $eventBus;
}
/**
* @param EventInterface $event
*
* @return EventInterface
*/
public function dispatch(EventInterface $event): EventInterface
{
$eventAdapter = new EventAdapter($event);
$this->messageBus->dispatch(new Envelope($eventAdapter));
return $eventAdapter;
}
}
This my service_test.yaml file which is taken into account when running Behat tests:
services:
_defaults:
autowire: true
autoconfigure: true
App\Features\BehatContext\:
resource: '../features/BehatContext/*'
App\Features\BehatContext\MessengerContext:
arguments:
$transport: '@messenger.transport.event'
Checking my logs I can see that the messenger did send the event:
[2019-08-30 14:14:50] messenger.INFO: Sending message App\EventAdapter with Symfony\Component\Messenger\Transport\InMemoryTransport {"message":"[object] (App\EventAdapter: {})","class":"App\EventAdapter","sender":"Symfony\Component\Messenger\Transport\InMemoryTransport"} []
Here's an up to date example for anyone stumbling across this using the when also using the MinkContext
<?php
declare(strict_types=1);
namespace App\Features\Bootstrap;
use Behat\Behat\Context\Context;
use Behat\Behat\Hook\Scope\BeforeScenarioScope;
use Behat\MinkExtension\Context\MinkContext;
use PHPUnit\Framework\Assert;
use Psr\Container\ContainerInterface;
use Symfony\Component\Messenger\Transport\InMemoryTransport;
/**
* @author Daniel West <daniel@silverback.is>
*/
class MessengerContext implements Context
{
private ContainerInterface $container;
/**
* @BeforeScenario
*/
public function getContexts(BeforeScenarioScope $scope): void
{
/** @var MinkContext $mink */
$mink = $scope->getEnvironment()->getContext(MinkContext::class);
$client = $mink->getSession()->getDriver()->getClient();
$container = $client->getContainer();
$this->container = $container->has('test.service_container') ? $container->get('test.service_container') : $container;
}
/**
* @Then /(\d+) message(?:s)? should have been sent to the transport named (.*)/
*/
public function messaesHaveBeenSentToTheTransport(int $count, string $name): void
{
/** @var InMemoryTransport $transport */
$transport = $this->container->get(sprintf('messenger.transport.%s', $name));
Assert::assertCount($count, $transport->get());
}
}