【问题标题】:Laravel Test That Job Is ReleasedLaravel 测试作业是否已发布
【发布时间】:2016-05-16 15:07:10
【问题描述】:

我想测试在某些情况下作业是否已释放回队列中。

这是我的工作课程:

class ChargeOrder extends Job
{
    use InteractsWithQueue, SerializesModels;

    /**
     * The order model which is to be charged
     */
    protected $order;

    /**
     * The token or card_id which allows us to take payment
     */
    protected $source;

    /**
     * Create a new job instance.
     *
     * @param   App\Order       $order;
     * @param   string          $source;
     * @return  array
     */
    public function __construct($order, $source)
    {
        $this->order        = $order;
        $this->source       = $source;
    }

    /**
     * Execute the job.
     *
     * @return void
     */
    public function handle(Charge $charge)
    {
        $result             = $charge->execute($this->source, $this->order->totalInclVat());
        $exception_errors   = config('payment.errors.exception_errors');

        //  If we have an error that isn't caused by the user (anything but a card error)
        //  We're going to notify ourselves via slack so we can investigate.
        if (array_key_exists('error', $result) && in_array($result['error']['code'], array_keys(config('payment.errors.other_error'))))
        {
            $client         = new Client(config('services.slack.channels.payment_errors.url'), config('services.slack.channels.payment_errors.settings'));
            $client->send(app()->environment() . ": " . $result['error']['code']);
        }

        //  If the error is in the list of errors that throw an exception, then throw it.
        if (array_key_exists('error', $result) && (in_array($result['error']['type'], $exception_errors) || in_array($result['error']['code'], $exception_errors)))
        {
            $status_code    = config('payment.errors')[$result['error']['type']][$result['error']['code']]['status_code'];
            $message        = config('payment.errors')[$result['error']['type']][$result['error']['code']]['message'];

            throw new BillingErrorException($status_code, $message);
        }

        //  If we still have an error, then it something out of the user's control.
        //  This could be a network error, or an error with the payment system
        //  Therefore, we're going to throw this job back onto the queue so it can be processed later.
        if (array_key_exists('error', $result) && in_array($result['error']['code'], array_keys(config('payment.errors.other_error'))))
        {
            $this->release(60);
        }
    }
}

我需要测试在某些情况下是否调用了“$this->release(60)”。

在我的测试中,我试图模拟工作合同:

// Set Up
$this->job  = Mockery::mock('Illuminate\Contracts\Queue\Job');
$this->app->instance('Illuminate\Contracts\Queue\Job', $this->job);

然后

// During Test
$this->job->shouldReceive('release')->once();

但这不起作用。

有人有什么想法吗?

【问题讨论】:

  • 您是否已经找到了可以分享的解决问题的方法?

标签: laravel testing jobs task-queue


【解决方案1】:

在调度作业之前尝试在测试中添加以下内容:

Queue::after(function (JobProcessed $event) {
    $this->assertTrue($event->job->isReleased());
});

上述代码将在作业完成后触发,并检查作业是否已释放。

确保删除对Queue::fake()$this->expectsJob()的所有调用,因为这些调用会阻止实际作业的执行。

【讨论】:

  • 对我不起作用。在测试中,我使用的是“同步”驱动程序。
【解决方案2】:

我通过创建一个仅在作业释放回队列后触发的事件解决了这个问题。然后在我的测试中,我可以在调度作业后使用 Event 模拟来监视该事件,并知道我们是否将其释放回队列中。

// In your job
$this->release();
event(new MyJobReleasedEvent()); // Every time you have a release() call

// In your Unit Test
Event::fake([MyJobReleasedEvent::class]);
dispatch(new MyJob();
Event::assertDispatched(MyJobReleasedEvent::class);

如果你想变得花哨,我相信你可以连接你自己的 Job 类,它会在调用 release() 时自动执行此操作,但我很少需要它,只需按需内联即可。

【讨论】:

  • 只有当我用类的 ...::class 替换 event(...) 参数时才有效。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-03-31
  • 2011-03-19
  • 1970-01-01
  • 2018-03-25
  • 1970-01-01
  • 1970-01-01
  • 2017-02-12
相关资源
最近更新 更多