Testing

Testing your events with WPZylos Events.

Unit Testing Events

Testing Event Dispatch

use PHPUnit\Framework\TestCase;
use WPZylos\Framework\Events\EventDispatcher;

class EventDispatcherTest extends TestCase
{
    private EventDispatcher $dispatcher;

    protected function setUp(): void
    {
        $this->dispatcher = new EventDispatcher();
    }

    public function testListenerReceivesEvent(): void
    {
        $received = null;

        $this->dispatcher->listen(UserCreated::class, function ($event) use (&$received) {
            $received = $event;
        });

        $event = new UserCreated($user);
        $this->dispatcher->dispatch($event);

        $this->assertSame($event, $received);
    }

    public function testStoppableEventStopsPropagation(): void
    {
        $callCount = 0;

        $this->dispatcher->listen(StoppableEvent::class, function ($event) use (&$callCount) {
            $callCount++;
            $event->stopPropagation();
        }, priority: 10);

        $this->dispatcher->listen(StoppableEvent::class, function () use (&$callCount) {
            $callCount++;
        }, priority: 5);

        $this->dispatcher->dispatch(new StoppableEvent());

        $this->assertEquals(1, $callCount);
    }
}

Testing Subscribers

class UserEventSubscriberTest extends TestCase
{
    public function testSubscriberRegistersAllEvents(): void
    {
        $events = UserEventSubscriber::getSubscribedEvents();

        $this->assertArrayHasKey(UserCreated::class, $events);
        $this->assertArrayHasKey(UserDeleted::class, $events);
    }

    public function testOnUserCreatedSendsEmail(): void
    {
        $mailer = $this->createMock(Mailer::class);
        $mailer->expects($this->once())
            ->method('send')
            ->with($this->isInstanceOf(WelcomeEmail::class));

        $subscriber = new UserEventSubscriber($mailer);
        $subscriber->onUserCreated(new UserCreated($user));
    }
}

Mock Dispatcher

Creating a Mock

class MockEventDispatcher implements EventDispatcherInterface
{
    public array $dispatched = [];

    public function dispatch(object $event): object
    {
        $this->dispatched[] = $event;
        return $event;
    }

    public function assertDispatched(string $eventClass): void
    {
        foreach ($this->dispatched as $event) {
            if ($event instanceof $eventClass) {
                return;
            }
        }
        throw new \AssertionError("Event {$eventClass} was not dispatched");
    }

    public function assertNotDispatched(string $eventClass): void
    {
        foreach ($this->dispatched as $event) {
            if ($event instanceof $eventClass) {
                throw new \AssertionError("Event {$eventClass} was dispatched");
            }
        }
    }
}

Using in Tests

class RegistrationControllerTest extends TestCase
{
    public function testRegistrationDispatchesEvent(): void
    {
        $dispatcher = new MockEventDispatcher();
        $controller = new RegistrationController($dispatcher);

        $controller->register(new Request(['email' => '[email protected]']));

        $dispatcher->assertDispatched(UserRegistered::class);
    }
}

Running Tests

# Run all tests
composer run test

# Run with coverage
vendor/bin/phpunit --coverage-html coverage