如何断言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
相关产品推荐
相关产品推荐

