如何在Laravel中测试带channel的Log::spy日志记录?
解决指定频道日志的测试问题
你遇到的核心问题是:Log::spy() 仅替换了日志门面的根实例,但未处理 channel() 方法的返回逻辑,导致调用 Log::channel('logistics') 时返回 null。以下是正确的测试方案:
测试代码实现
// 为指定频道创建日志 spy 实例 $logisticsLogSpy = \Mockery::spy(); // 让 Log 门面的 channel 方法,在传入 'logistics' 时返回这个 spy \Illuminate\Support\Facades\Log::shouldReceive('channel') ->with('logistics') ->andReturn($logisticsLogSpy); // 发送测试请求 $this->postJson( 'logistics/delivery', [ 'location_id' => $location->uuid, 'contents' => [ $case1->serial, ], ] )->assertUnprocessable(); // 断言指定频道的日志方法被正确调用 $logisticsLogSpy->shouldHaveReceived('info') ->withArgs(function ($message, $context) use ($case1) { $this->assertStringContainsString('Validation failed. Submitted serials:', $message); $this->assertArrayHasKey('contents', $context); $this->assertEquals([$case1->serial], $context['contents']); return true; });
原理说明
- 单独为
logistics频道创建 spy 实例,避免影响其他频道或全局日志的正常调用 - 通过
shouldReceive('channel')->with('logistics')拦截频道获取请求,返回我们创建的 spy - 最后直接针对该频道的 spy 做断言,精准验证目标日志行为
内容的提问来源于stack exchange,提问作者Synchro
相关产品推荐
相关产品推荐

