Laravel:队列工作如何运作?

时间:2018-02-05 22:38:46

标签: laravel testing phpunit integration-testing laravel-5.5

我正在使用Larevel 5.5的内置Redis队列。在我编写排队有效负载的测试时,我注意到测试无法识别我在queue.php中分配的默认队列名称:

'connections' => [
    'redis' => [
        'driver' => 'redis',
        'connection' => 'default',
        'queue' => 'tickets', 
    ]

我正在将负载插入队列,如下所示:Job::dispacth($payload)。它在实际的非测试代码中按预期工作。

我的测试代码:

public function testTicketQueue()
{
    Queue::fake();
    $payload = ['this is a ticket'];
    TicketProcessor::dispatch($payload)
        ->onQueue('tickets') // Fails without this
        ;
    Queue::assertPushedOn('tickets', TicketProcessor::class);
}
  1. 为什么不将有效负载发送到tickets队列?我必须为测试明确指定队列名称。即->onQueue('tickets')。如果它故意忽略它,我在哪里可以找到这种行为的参考?

  2. 我最终追溯dispatch()以了解为什么#1是如此,但我只是发现类Illuminate\Foundation\Bus\PendingDispatch的实例化很奇怪(见#3)下面:

    // Illuminate\Foundation\Bus\Dispatchable
    public static function dispatch()
    {
        return new PendingDispatch(new static(...func_get_args()));
    }
    
    // Illuminate\Foundation\Bus\PendingDispatch
    public function __construct($job)
    {
        $this->job = $job;
    }
    

    dispatch如何将有效负载插入队列?是基于事件的,魔术还是?

  3. new PendingDispatch(new static(...func_get_args()));究竟在做什么?具体来说,我不知道new static正在做什么作为构造函数的参数。 PendingDispatch的构造函数甚至不带多个参数。

1 个答案:

答案 0 :(得分:1)

对于#1,当单元测试时你不使用实际的队列实现,而是使用Laravel外观fake方法(类似于模拟)。事件,队列,总线,通知等外观都可以访问::fake()静态方法,作为模拟应用程序实现的便利包装。

如您所见,dispatch帮助程序只是包装创建PendingDispatch实例。 Dispatchable特征是它定义的地方。该队列通过序列化传递给它的类来工作,因此任何公开定义的属性都会自动在队列中可用。

new static正在引用您正在推送到队列的作业的类。基本上,使用传递给dispatch帮助器的所有参数创建自己的新实例。

使用PHP,您不需要提供方法签名,您可以定义如下方法:

public function myMethod()

并将其称为

$obj->myMethod($a, $b, $c, $d)

func_get_args()正在做什么,它正在调用传递给方法的所有参数。这才是神奇的。在上面的示例中,func_get_args()将返回数组[$a, $b, $c, $d]

相关问题