Laravel:队列作业如何工作?

标签 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 是这样,但我只是发现它是类的一个奇怪的(参见 #3)实例化 Illuminate\Foundation\Bus\PendingDispatch 如下所示:

    // 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,当单元测试时,您不使用实际的队列实现,而是使用 Laravel facades fake 方法(类似于 Mock)。 Event、Queue、Bus、Notification 等 Facade 都提供对 ::fake() 静态方法的访问,作为模拟应用程序实现的便利包装器。

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

new static 引用您推送到队列的作业类。基本上,使用传递给 dispatch 助手的所有参数创建一个新的 myself 实例。

使用 PHP,您不需要提供方法签名,您可以像这样定义一个方法:

public function myMethod()

并称它为

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

这就是 func_get_args() 正在做的事情,它将所有参数传递给被调用的方法。这就是魔法。在上面的示例中,func_get_args() 将返回一个数组 [$a, $b, $c, $d]

关于Laravel:队列作业如何工作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48632654/

相关文章:

phpunit - 使用 codeception 测试文件上传

unit-testing - PHPUnit 是否忽略 Zend Framework 2 中的 config/autoload/... 文件?

php - 如何创建一个单独的类来在表中创建新记录并通过 Controller 上的接口(interface)或外观调用它

python - Pytest:查找每个测试的开始和结束时间

java - Mockito:如何在测试中识别未使用的 .when()

angularjs - Protractor 所有 API 函数真的返回 promise 吗?

通过 Composer 和 PhpStorm 的 PHPUnit

javascript - 用于 ie 的 Polyfill

php - 如何根据用户在 Laravel 5 中的角色来选择用户?

php - Laravel 5 关机功能替代