I'm trying to mock laravel Log
. This is my code:
public function test_process_verify_card()
{
Log::shouldReceive('error')->once();
Log::makePartial();
$class = new MyClass();
$class->myFunction();
}
This is MyClass
look like:
class MyClass
{
public function __construct()
{
$this->logger = Logg::channel('test');
}
public function myFunction()
{
// ... some logic
$this->loggger->error('Errror!!');
}
}
When I run test this test case, it throw error
Call to a member function runningUnitTests() on null
at vendor/laravel/framework/src/Illuminate/Log/LogManager.php:568
I tried to debug this error by putting dd()
in LogManager
class
protected function parseDriver($driver)
{
$driver ??= $this->getDefaultDriver();
dd($this->app); // <--- This is my code
if ($this->app->runningUnitTests()) {
$driver ??= 'null';
}
return $driver;
}
But it show that $this->app
is not null
.
I've tried mock facade Date
before and it works fine.
I want to test that myFunction
executes logging action. Is this correct way to do it?
I also tried to mock it through partialMock()
function:
public function test_process_verify_card()
{
$this->partialMock(Logger::class, function (MockInterface $mock) {
$mock->shouldReceive('error')->once();
});
$class = new MyClass();
$class->myFunction();
}
But it still not works, it shows error:
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
I would believe the problem why this is not working, is as Log::channel
returns a channel on the partial mock. Therefor the mocked instance never receive the error call.
In Mockery
you can easily do chained calls, by using '->' in the shouldReceive()
call.
Log::shouldReceive('channel->error')
->once()
->andReturn(null);