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

Laravel 9中Log断言失败:期望调用1次实际0次的解决方案咨询

Laravel 9测试中Log::info断言失败但实际日志存在的解决办法

下面是针对这个问题的几种排查和解决方向:

  • 调整Mock的执行顺序
    必须在发起接口请求之前定义Log的mock断言,否则日志已经输出后再设置mock就无法捕获到调用记录。示例代码:

    public function it_can_keep_sale_order()
    {
        // 先设置Log的调用期望
        Log::shouldReceive('info')
            ->once()
            ->with(\Mockery::pattern('/Creating sales order/'));
    
        // 再执行接口请求
        $response = $this->post('/api/sale-orders', [/* 请求参数 */]);
    
        // 验证响应结果
        $response->assertStatus(201);
    }
    
  • 使用Partial Mock保留原有日志行为
    完全mock Log facade可能会导致断言与实际日志输出的逻辑脱节,改用partial mock可以在捕获调用的同时保留原有日志写入能力:

    public function it_can_keep_sale_order()
    {
        Log::partialMock()
            ->shouldReceive('info')
            ->once()
            ->with(\Mockery::contains('Creating sales order'));
    
        $response = $this->post('/api/sale-orders', [/* 请求参数 */]);
        $response->assertStatus(201);
    }
    
  • 处理队列任务中的日志输出
    如果日志是在异步队列任务中生成的,默认测试不会等待队列执行,需要临时开启同步队列模式:

    public function it_can_keep_sale_order()
    {
        // 将队列设置为同步模式,任务立即执行
        $this->app['config']->set('queue.default', 'sync');
    
        Log::shouldReceive('info')
            ->once()
            ->with(\Mockery::contains('Creating sales order'));
    
        $response = $this->post('/api/sale-orders', [/* 请求参数 */]);
        $response->assertStatus(201);
    }
    
  • 确认Log Facade的命名空间
    确保测试类顶部正确引入Laravel官方的Log facade,避免使用自定义的Log类导致mock对象不匹配:

    use Illuminate\Support\Facades\Log; // 必须使用这个命名空间
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 04:21:49