Skip to content

Instantly share code, notes, and snippets.

@rommsen
Last active October 5, 2016 12:28
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rommsen/d1763ff1f008cf15c6a436ea32de3bd9 to your computer and use it in GitHub Desktop.
Save rommsen/d1763ff1f008cf15c6a436ea32de3bd9 to your computer and use it in GitHub Desktop.
Behat with prooph
<?php
namespace Ipark\ApplicationBundle\Behat\Util;
use Prooph\Common\Messaging\Message;
use Prooph\EventSourcing\AggregateRoot;
use Prooph\EventSourcing\EventStoreIntegration\AggregateTranslator;
use Prooph\EventStore\Aggregate\AggregateType;
use Prooph\ServiceBus\EventBus;
use Prooph\ServiceBus\Plugin\Router\RegexRouter;
trait EventChecker
{
/**
* @var AggregateTranslator
*/
private $aggregateTranslator;
/**
* @var Message
*/
private $events;
/**
* @param AggregateRoot $aggregateRoot
* @return Message[]
*/
protected function popRecordedEvent(AggregateRoot $aggregateRoot)
{
return $this->getAggregateTranslator()->extractPendingStreamEvents($aggregateRoot);
}
/**
* @param string $aggregateRootClass
* @param array $events
* @return object
*/
protected function reconstituteAggregateFromHistory($aggregateRootClass, array $events)
{
return $this->getAggregateTranslator()->reconstituteAggregateFromHistory(
AggregateType::fromAggregateRootClass($aggregateRootClass),
new \ArrayIterator($events)
);
}
/**
* Define an additional catchall router and add it to a specific event bus
* The recorded events are stored in $this->events
* @param $eventBus
*/
protected function startCollectingEventsFromBus(EventBus $eventBus)
{
// define a new
$router = new RegexRouter();
$router->route(RegexRouter::ALL)->to(function ($event) {
$this->events[] = $event;
});
$eventBus->utilize($router);
}
/**
* @return AggregateTranslator
*/
private function getAggregateTranslator()
{
if (null === $this->aggregateTranslator) {
$this->aggregateTranslator = new AggregateTranslator();
}
return $this->aggregateTranslator;
}
}
<?php
namespace Ipark\ApplicationBundle\Behat\Context\Application\Agency\ResourcePlanning;
use Behat\Symfony2Extension\Context\KernelDictionary;
use Ipark\ApplicationBundle\Behat\Context\Application\ApplicationContext;
use Ipark\ApplicationBundle\Behat\Util\EventChecker;
use Ipark\Model\ResourcePlanning\Standort\AktionsstandortId;
use Ipark\Model\ResourcePlanning\Standort\Command\LoescheStandort;
use Ipark\Model\ResourcePlanning\Standort\Command\OrdneAktionsstandortZuStandortZu;
use Ipark\Model\ResourcePlanning\Standort\Event\AktionsstandortWurdeZuStandortZugeordnet;
use Ipark\Model\ResourcePlanning\Standort\Event\StandortWurdeGeloescht;
use Ipark\Model\ResourcePlanning\Standort\Exception\InterneStandortIdentifikationsnummerBereitsVergeben;
use Ipark\Model\ResourcePlanning\Standort\StandortId;
use PHPUnit_Framework_Assert as Assert;
use Prooph\ServiceBus\Exception\CommandDispatchException;
class StandortContext extends ApplicationContext
{
use KernelDictionary;
use EventChecker;
/**
* @var StandortId
*/
private $standortId;
/**
* @var AktionsstandortId
*/
private $aktionsstandortId;
/**
* @When ich einen vorhandenen Standort lösche
*/
public function ichEinenVorhandenenStandortLosche()
{
// utility method
$this->standortId = $this->erstelleStandort();
// we start to record after the creation because we dont care about previous events
$this->startCollectingEventsFromBus($this->getContainer()->get('ipark.resource_planning.messaging.service_bus.event_bus'));
$this->dispatchOnResourcePlanningBus(LoescheStandort::mitId($this->standortId));
}
/**
* @Then sollte der Standort nicht mehr vorhanden sein
*/
public function sollteDerStandortNichtMehrVorhandenSein()
{
// we can assert the number and type of the recorded events
Assert::assertCount(1, $this->events);
Assert::assertInstanceOf(StandortWurdeGeloescht::class, $this->events[0]);
Assert::assertEquals($this->standortId, $this->events[0]->standortId());
}
/**
* @Given ich einen Standort mit der internen Identifikationsnummer abc angelegt habe
*/
public function ichEinenStandortMitDerInternenIdentifikationsnummerAbcAngelegtHabe()
{
$this->standortId = $this->erstelleStandort('abc');
}
/**
* @When ich einen weiteren Standort mit der selben internen Identifikationsnummer anlegen möchte
*/
public function ichEinenWeiterenStandortMitDerSelbenInternenIdentifikationsnummerAnlegenMochte()
{
// example how to test exceptions during dispatching of command
try {
$this->standortId = $this->erstelleStandort('abc');
} catch (CommandDispatchException $e) {
if (get_class($e->getPrevious()) == InterneStandortIdentifikationsnummerBereitsVergeben::class) {
return;
}
}
throw new \Exception("Another aggregate with the internal identifier was created, this should not have happened");
}
/**
* @Then sollte dies nicht möglich sein, da es bereits einen Standort mit der internen Identifikationsnummer abc gibt
*/
public function sollteDiesNichtMoglichSeinDaEsBereitsEinenStandortMitDerInternenIdentifikationsnummerAbcGibt()
{
}
/**
* @When ich einen Aktionsstandort einem bereits bestehenden Standort zuordne
*/
public function ichEinenAktionsstandortEinemBereitsBestehendenStandortZuordne()
{
$this->standortId = $this->erstelleStandort();
$this->aktionsstandortId = $this->erstelleAktionsstandort();
$this->startCollectingEventsFromBus($this->getContainer()->get('ipark.resource_planning.messaging.service_bus.event_bus'));
$this->dispatchOnResourcePlanningBus(
OrdneAktionsstandortZuStandortZu::mitIds($this->aktionsstandortId, $this->standortId)
);
}
/**
* @Then sollte der Aktionsstandort dem Standort zugeordnet sein
*/
public function sollteDerAktionsstandortDemStandortZugeordnetSein()
{
Assert::assertCount(1, $this->events);
Assert::assertInstanceOf(AktionsstandortWurdeZuStandortZugeordnet::class, $this->events[0]);
Assert::assertEquals($this->standortId, $this->events[0]->standortId());
Assert::assertEquals($this->aktionsstandortId, $this->events[0]->aktionsstandortId());
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment