How to test broadcast driver?

Viewed 5529

I am wondering if its possible to test ShouldBroadcast in Laravel? My test will trigger the even that implements ShouldBroadcast, however, I've noticed that broadcasting didn't happen.

Of course, the broadcasting event is working in the app it self.

Has any one tried such test?

4 Answers

Instead of checking what's written in log, you can to use the assertion 'expectsEvents', which you can test if a certain event is launched.

public function testMethod(){
   $this->expectsEvents(YourEventClass::class)
    ...your code test...
}

For more info: https://laravel-guide.readthedocs.io/en/latest/mocking/

with Adrienc solutions with dynamically getting index of last event

private function getIndexOfLoggedEvent(array $logfile)
{
    for ($i = count($logfile) - 1; $i >=0 ; $i--) {
        if (strpos($logfile[$i], 'Broadcasting [Illuminate\Notifications\Events\BroadcastNotificationCreated]') !== false) {
            return $i;
        }
    }
}

which will give you index of the line of last broadcast

I took both previous answers, and put them together.

This works with laravel 5.7.

In your TestCase.php file:

public function assertEventIsBroadcasted($eventClassName, $channel = '')
{
    $date = Carbon::now()->format('Y-m-d');
    $logfileFullpath = storage_path("logs/laravel-{$date}.log");
    $logfile = explode("\n", file_get_contents($logfileFullpath));
    $indexOfLoggedEvent = $this->getIndexOfLoggedEvent($logfile);

    if ($indexOfLoggedEvent) {
        $supposedLastEventLogged = $logfile[$indexOfLoggedEvent];
        $this->assertContains('Broadcasting [', $supposedLastEventLogged, "No broadcast were found.\n");

        $this->assertContains(
            'Broadcasting [' . $eventClassName . ']',
            $supposedLastEventLogged,
            "A broadcast was found, but not for the classname '" . $eventClassName . "'.\n"
        );

        if ($channel != '') {
            $this->assertContains(
                'Broadcasting [' . $eventClassName . '] on channels [' . $channel . ']',
                $supposedLastEventLogged,
                'The expected broadcast (' . $eventClassName . ") event was found, but not on the expected channel '" . $channel . "'.\n"
            );
        }
    } else {
        $this->fail("No informations found in the file log '" . $logfileFullpath . "'.");
    }
}

private function getIndexOfLoggedEvent(array $logfile)
{
    for ($i = count($logfile) - 1; $i >= 0; $i--) {
        if (strpos($logfile[$i], 'local.INFO: Broadcasting') !== false) {
            return $i;
        }
    }
    return false;
}

A test could look like this:

/**
 * @test
 */
public function notifications_are_broadcasted()
{
    $notification = factory(Notification::class)->create();
    broadcast(new NewNotification($notification));
    $this->assertEventIsBroadcasted(
        NewNotificationEvent::class,
        'private-notification.' . $notification->id
    );
}
Related