我正在使用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);
}
为什么不将有效负载发送到tickets
队列?我必须为测试明确指定队列名称。即->onQueue('tickets')
。如果它故意忽略它,我在哪里可以找到这种行为的参考?
我最终追溯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
如何将有效负载插入队列?是基于事件的,魔术还是?
new PendingDispatch(new static(...func_get_args()));
究竟在做什么?具体来说,我不知道new static
正在做什么作为构造函数的参数。 PendingDispatch
的构造函数甚至不带多个参数。
答案 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]
。