无法在 Laravel 中模拟部分 Log 外观

sim*_*ns3 4 php testing mocking laravel

我想嘲笑 laravel Log。这是我的代码:

public function test_process_verify_card()
{
    Log::shouldReceive('error')->once();
    Log::makePartial();
    $class = new MyClass();
    $class->myFunction();
}
Run Code Online (Sandbox Code Playgroud)

MyClass看起来像:

class MyClass
{
    public function __construct()
    {
        $this->logger = Logg::channel('test');
    }

    public function myFunction()
    {
        // ... some logic
        $this->loggger->error('Errror!!');
    }
}
Run Code Online (Sandbox Code Playgroud)

当我运行测试这个测试用例时,它抛出错误

Call to a member function runningUnitTests() on null

  at vendor/laravel/framework/src/Illuminate/Log/LogManager.php:568
Run Code Online (Sandbox Code Playgroud)

我尝试通过放入类dd()中来调试此错误LogManager

    protected function parseDriver($driver)
    {
        $driver ??= $this->getDefaultDriver();
        dd($this->app); // <--- This is my code
        if ($this->app->runningUnitTests()) {
            $driver ??= 'null';
        }

        return $driver;
    }
Run Code Online (Sandbox Code Playgroud)

但它表明事实$this->app并非如此null

我之前尝试过模拟外观Date,效果很好。

我想测试myFunction执行日志操作。这是正确的方法吗?

更新

我还尝试通过partialMock()函数来​​模拟它:

    public function test_process_verify_card()
    {
        $this->partialMock(Logger::class, function (MockInterface $mock) {
            $mock->shouldReceive('error')->once();
        });
        $class = new MyClass();
        $class->myFunction();
    }
Run Code Online (Sandbox Code Playgroud)

但还是不行,显示错误:

  Method error(<Any Arguments>) from Mockery_0_Illuminate_Log_Logger should be called
 exactly 1 times but called 0 times.

  at vendor/phpunit/phpunit/phpunit:98
Run Code Online (Sandbox Code Playgroud)

mrh*_*rhn 5

我相信为什么这不起作用的问题是Log::channel在部分模拟上返回一个通道。因此,模拟实例永远不会收到错误调用。

通过Mockery在调用中使用“->”,您可以轻松地进行链式调用shouldReceive()

Log::shouldReceive('channel->error')
    ->once()
    ->andReturn(null);
Run Code Online (Sandbox Code Playgroud)