diff --git a/README.md b/README.md index 135e6e1..fa93978 100644 --- a/README.md +++ b/README.md @@ -167,7 +167,7 @@ final class ProfileTest extends AggregateRootTestCase For testing a subscriber there is a utility class which you can use. Using `SubscriberUtilities` will provide you a bunch of dx features which makes the testing easier. First, you will need to provide the utility class the subscriptions -you will want to test, this is done when initialiszing the class. After that, you can call these 3 methods: +you will want to test, this is done when initializing the class. After that, you can call these 3 methods: `executeSetup`, `executeRun` and `executeTeardown`. These methods will be calling the right methods which are defined via the attributes. For our example we are taking as simplified subscriber: @@ -232,4 +232,56 @@ final class ProfileSubscriberTest extends TestCase } ``` -This Util class can be used for integration or unit tests. \ No newline at end of file +This Util class can be used for integration or unit tests. + +You can also pass `Message` instances with additional headers to the `executeRun` method. This allows testing +subscribers that rely on additional parameters like header information: + + +```php +use Patchlevel\EventSourcing\Attribute\Subscribe; +use Patchlevel\EventSourcing\Attribute\Subscriber; +use DateTimeImmutable; + +#[Subscriber('profile_subscriber', RunMode::FromBeginning)] +final class ProfileSubscriber +{ + #[Subscribe(ProfileCreated::class)] + public function run(ProfileCreated $event, DateTimeImmutable $recordedOn): void + { + } +} +``` + +Add any headers you want in the test: + +```php +use Patchlevel\EventSourcing\Attribute\Subscriber; +use Patchlevel\EventSourcing\Message\Message; +use Patchlevel\EventSourcing\Store\Header\RecordedOnHeader; +use Patchlevel\EventSourcing\Subscription\RunMode; +use Patchlevel\EventSourcing\PhpUnit\Test\SubscriberUtilities; +use DateTimeImmutable; + +final class ProfileSubscriberTest extends TestCase +{ + use SubscriberUtilities; + + public function testProfileCreated(): void + { + /* Setup and Teardown as before */ + + $util->executeRun( + Message::createWithHeaders( + new ProfileCreated( + ProfileId::fromString('1'), + Email::fromString('hq@patchlevel.de'), + ), + [new RecordedOnHeader(new DateTimeImmutable('now'))], + ) + ); + + /* Your assertions */ + } +} +``` \ No newline at end of file diff --git a/composer.json b/composer.json index b8c20c3..fabbc80 100644 --- a/composer.json +++ b/composer.json @@ -22,7 +22,7 @@ ], "require": { "php": "~8.2.0 || ~8.3.0 || ~8.4.0 || ~8.5.0", - "patchlevel/event-sourcing": "^3.10.0", + "patchlevel/event-sourcing": "^3.13.0", "phpunit/phpunit": "^10.5.45 || ^11.0.0 || ^12.0.0" }, "require-dev": { diff --git a/src/Test/SubscriberUtilities.php b/src/Test/SubscriberUtilities.php index a9e49e5..7bc1b97 100644 --- a/src/Test/SubscriberUtilities.php +++ b/src/Test/SubscriberUtilities.php @@ -55,9 +55,13 @@ public function executeRun(object ...$events): self $subscriberAccessors = $this->subscriberAccessorRepository->all(); foreach ($events as $event) { + if (!$event instanceof Message) { + $event = Message::create($event); + } + foreach ($subscriberAccessors as $subscriberAccessor) { - foreach ($subscriberAccessor->subscribeMethods($event::class) as $subscribeMethod) { - $subscribeMethod(Message::create($event)); + foreach ($subscriberAccessor->subscribeMethods($event->event()::class) as $subscribeMethod) { + $subscribeMethod($event); } } } diff --git a/tests/Unit/Test/SubscriberUtilitiesTest.php b/tests/Unit/Test/SubscriberUtilitiesTest.php index 4268ce2..a56678b 100644 --- a/tests/Unit/Test/SubscriberUtilitiesTest.php +++ b/tests/Unit/Test/SubscriberUtilitiesTest.php @@ -4,14 +4,17 @@ namespace Patchlevel\EventSourcing\PhpUnit\Tests\Unit\Test; +use DateTimeImmutable; use Patchlevel\EventSourcing\Attribute\Projector; use Patchlevel\EventSourcing\Attribute\Setup; use Patchlevel\EventSourcing\Attribute\Subscribe; use Patchlevel\EventSourcing\Attribute\Teardown; +use Patchlevel\EventSourcing\Message\Message; use Patchlevel\EventSourcing\PhpUnit\Test\SubscriberUtilities; use Patchlevel\EventSourcing\PhpUnit\Tests\Unit\Fixture\Email; use Patchlevel\EventSourcing\PhpUnit\Tests\Unit\Fixture\ProfileCreated; use Patchlevel\EventSourcing\PhpUnit\Tests\Unit\Fixture\ProfileId; +use Patchlevel\EventSourcing\Store\Header\RecordedOnHeader; use PHPUnit\Framework\Attributes\CoversClass; use PHPUnit\Framework\TestCase; @@ -42,6 +45,34 @@ public function run(): void self::assertSame(1, $subscriber->called); } + public function testCanPassMessagesWithHeaders(): void + { + $recordedOn = new DateTimeImmutable('now'); + $subscriber = new #[Projector('test')] + class { + public DateTimeImmutable|null $recordedOn = null; + + #[Subscribe(ProfileCreated::class)] + public function run(ProfileCreated $event, DateTimeImmutable $recordedOn): void + { + $this->recordedOn = $recordedOn; + } + }; + + $util = new SubscriberUtilities($subscriber); + $util->executeRun( + Message::createWithHeaders( + new ProfileCreated( + ProfileId::fromString('1'), + Email::fromString('hq@patchlevel.de'), + ), + [new RecordedOnHeader($recordedOn)], + ), + ); + + self::assertEquals($recordedOn, $subscriber->recordedOn); + } + public function testRunNotFound(): void { $subscriber = new #[Projector('test')]