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
相关产品推荐
相关产品推荐

