如何测试广播驱动程序?

时间:2016-03-15 11:40:25

标签: laravel laravel-5.1 laravel-5.2

我想知道是否有可能在Laravel中测试ShouldBroadcast? 我的测试将触发实现ShouldBroadcast的偶数,但是,我注意到广播没有发生。

当然,广播活动正在自己的应用程序中运行。

有没有人尝试过这样的测试?

4 个答案:

答案 0 :(得分:4)

这是一个老问题,但万一它可以帮助某人:我为自己做了一个断言函数,你应该添加到你的TestCase.php。

我的想法是将广播驱动程序设置为“log”,然后从末尾读取第4行以查看它是否是广播日志。

在您的phpunit.xml中

将以下行添加到节点:

<env name="BROADCAST_DRIVER" value="log"/>

在TestCase.php文件中

添加以下功能:

public function assertEventIsBroadcasted($eventClassName, $channel=""){
  $logfileFullpath = storage_path("logs/laravel.log");
  $logfile = explode("\n", file_get_contents($logfileFullpath));

  if(count($logfile) > 4){
    $supposedLastEventLogged = $logfile[count($logfile)-5];

    $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."'.");
  }
}

答案 1 :(得分:1)

使用Adrienc解决方案,可以动态获取上一个事件的索引

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;
        }
    }
}

这将为您提供上次广播的行的索引

答案 2 :(得分:0)

我把前面的两个答案都整理了。

这适用于laravel 5.7。

在您的 TestCase.php 文件中:

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;
}

一个测试可能看起来像这样:

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

答案 3 :(得分:0)

您可以使用断言“ expectsEvents”来检查日志中的内容,而可以断言“ expectsEvents”。

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

有关更多信息:  https://laravel-guide.readthedocs.io/en/latest/mocking/