Installation Add the package via Composer:
composer require --dev timacdonald/log-fake
Register the service provider in config/app.php (if not auto-discovered):
'providers' => [
// ...
Timacdonald\LogFake\LogFakeServiceProvider::class,
],
Basic Usage
Replace Laravel’s default logger with LogFake in your test setup:
use Timacdonald\LogFake\LogFake;
public function test_logging()
{
LogFake::shouldReceive('info')
->once()
->with('Test message');
Log::info('Test message');
}
First Use Case
Log::info(), Log::error(), etc., with LogFake to assert log messages in tests.Asserting Logged Messages
LogFake::assertLogged('Test message'); // Checks if message exists
LogFake::assertLoggedTimes(1, 'Test message'); // Checks exact count
Testing Log Channels
LogFake::shouldReceive('channel->error')
->once()
->with('Error in channel', ['context' => 'key']);
Log::channel('custom')->error('Error in channel', ['context' => 'key']);
Resetting Fake Logs
LogFake::reset(); // Clears all recorded logs between tests
Testing Log Levels
LogFake::shouldReceive('emergency')
->never(); // Assert no emergency logs were called
Log Facade: Replace Log with LogFake in tests by binding it in setUp():
public function setUp(): void
{
parent::setUp();
$this->app->singleton(\Illuminate\Log\LoggerInterface::class, function () {
return LogFake::make();
});
}
LogFake to add domain-specific checks:
LogFake::assertErrorContains('Failed', 'Expected error message');
Forgetting to Reset
LogFake::reset() in tearDown() or at the start of each test.Channel-Specific Mocking
Log::channel('custom') requires explicit channel binding in LogFake.LogFake::channel('custom')->shouldReceive() for channel-specific assertions.Context/Stack Data
['user' => ['id' => 1]]) requires precise matching.withArgs() or with() for complex context checks:
LogFake::shouldReceive('info')
->once()
->withArgs(['Test', ['user' => ['id' => 1]]]);
Global State in Tests
LogFake is global; shared state can cause test pollution.LogFake::fake() to create isolated instances per test class.dd(LogFake::getLogs());
shouldReceive() with andReturnSelf() for chained assertions:
LogFake::shouldReceive('info')
->andReturnSelf()
->once();
Custom Log Levels
Extend LogFake to support custom levels (e.g., debug, verbose):
LogFake::shouldReceive('debug')->once();
Log::debug('Debug message');
Log Formatting
Override LogFake::formatLog() to standardize log output for assertions:
LogFake::formatLog = fn($level, $message, $context) => "[$level] $message";
Integration with Testing Libraries Combine with Pest or PHPUnit matchers for fluent assertions:
expect(LogFake::getLogs())->toHaveCount(1);
How can I help you explore Laravel packages today?