You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何断言Laravel Bus批处理finally回调中SearchFallBack已调度?

Laravel 批量任务 finally 块中 Fallback 任务的断言方案

问题背景

我写了一段 Laravel 批量任务代码,在 finally 块里会根据条件触发 SearchFallBack 同步任务:

Bus::batch([
  new SearchA($a),
  new SearchB($a),
  new SearchC($a),
  new SearchD($a),
  new SearchE($a),
  new SearchF($a),
])
->finally(function (Batch $batch) {
  Log::info('Batch finished');

  if ($condition === true) {
    Log::info('all batch jobs returned no result, falling back');
    SearchFallBack::dispatchSync($a);
  }
})
->name('batch-name')
->dispatch();

目前已经能断言批量任务的名称和任务数:

Bus::assertBatched(function (PendingBatchFake $batch) {
  return $batch->name == 'batch-name' && $batch->jobs->count() === 6;
});

但卡在了如何验证当 $condition 为 true 时,SearchFallBack 确实被调度了。


解决思路

Laravel 的 Bus Fake 默认不会自动执行 finally 回调,需要手动触发。同时要确保 $condition 的值符合触发逻辑,之后就能断言任务是否被调度。

1. 拦截批量任务并执行

先通过 Bus::fake() 拦截所有任务调度,然后执行批量任务代码获取实例:

Bus::fake();
$a = 'test-data';
$condition = true; // 提前设置条件为true,满足触发fallback的要求

// 执行批量任务
$batch = Bus::batch([
  new SearchA($a),
  new SearchB($a),
  new SearchC($a),
  new SearchD($a),
  new SearchE($a),
  new SearchF($a),
])
->finally(function (Batch $batch) use ($condition, $a) {
  Log::info('Batch finished');

  if ($condition === true) {
    SearchFallBack::dispatchSync($a);
  }
})
->name('batch-name')
->dispatch();

2. 手动触发 finally 回调

通过 Bus::findBatch() 获取 Fake 批量任务实例,然后调用 callFinallyCallbacks() 执行 finally 块逻辑:

$fakeBatch = Bus::findBatch($batch->id);
$fakeBatch->callFinallyCallbacks();

3. 断言 Fallback 任务被调度

用 Bus::assertDispatchedSync() 验证 SearchFallBack 是否被正确调度,还可以校验任务参数:

Bus::assertDispatchedSync(SearchFallBack::class, function ($job) use ($a) {
  return $job->a === $a; // 确认任务携带的参数正确
});

完整测试代码

public function test_batch_triggers_fallback_when_condition_met()
{
    Bus::fake();
    $a = 'test-value';
    $condition = true;

    // 执行批量任务
    $batch = Bus::batch([
        new SearchA($a),
        new SearchB($a),
        new SearchC($a),
        new SearchD($a),
        new SearchE($a),
        new SearchF($a),
    ])
    ->finally(function (Batch $batch) use ($condition, $a) {
        if ($condition === true) {
            SearchFallBack::dispatchSync($a);
        }
    })
    ->name('batch-name')
    ->dispatch();

    // 断言批量任务基本信息
    Bus::assertBatched(function (PendingBatchFake $batch) {
        return $batch->name === 'batch-name' && $batch->jobs->count() === 6;
    });

    // 触发finally回调
    $fakeBatch = Bus::findBatch($batch->id);
    $fakeBatch->callFinallyCallbacks();

    // 断言fallback任务被调度
    Bus::assertDispatchedSync(SearchFallBack::class, function ($job) use ($a) {
        return $job->a === $a;
    });
}

内容的提问来源于stack exchange,提问作者lergoen

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.28 07:35:03