Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Log Fake Laravel Package

timacdonald/log-fake

View on GitHub
Deep Wiki
Context7

Getting Started

First Steps

  1. 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,
    ],
    
  2. 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');
    }
    
  3. First Use Case

    • Mocking Log Calls: Replace Log::info(), Log::error(), etc., with LogFake to assert log messages in tests.
    • Verify Logged Data: Check if specific messages, channels, or contexts were logged.

Implementation Patterns

Common Workflows

  1. Asserting Logged Messages

    LogFake::assertLogged('Test message'); // Checks if message exists
    LogFake::assertLoggedTimes(1, 'Test message'); // Checks exact count
    
  2. Testing Log Channels

    LogFake::shouldReceive('channel->error')
           ->once()
           ->with('Error in channel', ['context' => 'key']);
    
    Log::channel('custom')->error('Error in channel', ['context' => 'key']);
    
  3. Resetting Fake Logs

    LogFake::reset(); // Clears all recorded logs between tests
    
  4. Testing Log Levels

    LogFake::shouldReceive('emergency')
           ->never(); // Assert no emergency logs were called
    

Integration Tips

  • Use with Laravel’s 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();
        });
    }
    
  • Extend for Custom Assertions: Override LogFake to add domain-specific checks:
    LogFake::assertErrorContains('Failed', 'Expected error message');
    

Gotchas and Tips

Pitfalls

  1. Forgetting to Reset

    • Issue: Logs accumulate across test methods, causing false positives.
    • Fix: Call LogFake::reset() in tearDown() or at the start of each test.
  2. Channel-Specific Mocking

    • Issue: Mocking Log::channel('custom') requires explicit channel binding in LogFake.
    • Fix: Use LogFake::channel('custom')->shouldReceive() for channel-specific assertions.
  3. Context/Stack Data

    • Issue: Asserting nested contexts (e.g., ['user' => ['id' => 1]]) requires precise matching.
    • Fix: Use withArgs() or with() for complex context checks:
      LogFake::shouldReceive('info')
             ->once()
             ->withArgs(['Test', ['user' => ['id' => 1]]]);
      
  4. Global State in Tests

    • Issue: LogFake is global; shared state can cause test pollution.
    • Fix: Use LogFake::fake() to create isolated instances per test class.

Debugging Tips

  • Inspect Logs: Dump recorded logs for debugging:
    dd(LogFake::getLogs());
    
  • Verify Mocks: Use shouldReceive() with andReturnSelf() for chained assertions:
    LogFake::shouldReceive('info')
           ->andReturnSelf()
           ->once();
    

Extension Points

  1. Custom Log Levels Extend LogFake to support custom levels (e.g., debug, verbose):

    LogFake::shouldReceive('debug')->once();
    Log::debug('Debug message');
    
  2. Log Formatting Override LogFake::formatLog() to standardize log output for assertions:

    LogFake::formatLog = fn($level, $message, $context) => "[$level] $message";
    
  3. Integration with Testing Libraries Combine with Pest or PHPUnit matchers for fluent assertions:

    expect(LogFake::getLogs())->toHaveCount(1);
    
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
jayeshmepani/jpl-moshier-ephemeris-php
elnasnato/laraliveui
labrodev/rest-sdk
sampaui/sampaui
babelqueue/php-sdk
facebook/capi-param-builder-php
babelqueue/symfony
hamzi/corewatch
minionfactory/raw-hydrator
hexters/coinpayment
rjcodes/rjcms
act-training/laravel-permissions-manager
alimarchal/laravel-chart-of-accounts
babenkoivan/elastic-scout-driver
mkwebdesign/filament-watchdog-v5
renatomarinho/laravel-page-speed
zedmagdy/filament-business-hours
renatovdemoura/blade-elements-ui
devgeek/beacon-admin
benjamin-rqt/data-watcher-bundle