You need to enable JavaScript to run this app. Laravel使用PHPUnit测试Artisan命令时assertPushed校验始终失败
优惠活动
大模型
产品
解决方案
定价
更多

Laravel使用PHPUnit测试Artisan命令时assertPushed校验始终失败

问题根因
  • dispatchNow 逻辑与队列模拟机制不兼容
    Laravel 的 dispatchNow() 是同步直接执行任务的方法,完全跳过队列推送的全流程,不会向队列写入任何任务实例。哪怕你启用了 Queue::fake() 模拟队列环境,也捕获不到任何队列推送动作,这是断言失败的核心原因。
  • 测试未预置对应业务数据
    测试中直接调用 Artisan 命令,但没有提前创建 Model 的测试记录,命令内的 Model::query()->cursor() 遍历不到任何数据,each 闭包根本不会执行。就算把 dispatchNow 换成普通队列分发方法,也不会有任何 Job 被触发。
修复方案

根据你的实际业务需求选择对应改法:

方案1:符合批量迁移防内存溢出的队列执行场景

如果你本来就打算把任务推送到队列执行(每个 Job 单独进程运行,彻底避免内存溢出),需要先调整命令内的分发逻辑:

// 替换原来的同步分发写法
TestJob::dispatch($model);

再调整测试代码,先预置测试数据,再匹配对应的断言:

public function test_command_dispatch_job()
{
    Queue::fake();
    // 提前创建测试用的Model记录,保证游标能遍历到有效数据
    Model::factory()->count(2)->create();

    Artisan::call('random:test-job');

    // 断言推送的Job数量和实际创建的Model数量一致
    Queue::assertPushed(TestJob::class, 2);
}

方案2:确实需要同步执行任务的场景

如果你的设计就是要同步跑任务、不走队列,那不能用 Queue::fake() 做断言,需要换成任务总线的模拟工具 Bus::fake():

public function test_command_dispatch_job()
{
    Bus::fake();
    Model::factory()->count(2)->create();

    Artisan::call('random:test-job');

    // 断言任务被正确分发到总线执行
    Bus::assertDispatched(TestJob::class, 2);
}

额外提醒:你最初提到要处理2万条记录避免内存溢出,如果用 dispatchNow 同步执行,哪怕用了游标减少内存占用,Job 内的业务逻辑如果累积占用内存,还是可能触发溢出。批量迁移场景优先用队列分发的模式更稳妥。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.11.07 06:45:04