PHP Unit, Testing laravel log messages with unit testing
Asked Answered
C

3

11

I'm using PHPUnit to create a Unit test for a store function that stores data in a database.

Currently, i have a test verifies that it has stored data.

However, I also want to create a test that proves that a laravel log message has been produced if the model save function fails.

The code below shows the store function. The "log::info" is the line I want to test.

Thanks.

public function store(Venue $venue){ 
    $saved =  $venue->save();
    if($saved == false){
        Log::info('Failed to Save Venue'. $venue);
    }
 }

This what I have so far, i pass an empty model that will cause the save to fail due to database constraints

public function test_venue_store_failed(){
   $venue = new Venue();
   $venueRepo = new VenueRepository();
   $this->withExceptionHandling();
   $venueRepo->store($venue);
}
Chondrule answered 9/7, 2018 at 13:6 Comment(3)
Maybe with something like if(!$saved){ $saved = 'Failed to Save Venue'. $venue; Log::info($saved); } return $saved; Editor
Below I have answered with 3 ideas :), Hope one of them will help to solve your problem.Kelliekellina
I do think so . May be you should try with debuging $saved instead of $venue. or do dumping $venue before saving.Hymenopteran
H
36

You can mock the Log facade in your unit test as follows, as per the docs:

public function test_venue_store_failed(){
    $venue = new Venue();

    Log::shouldReceive('info')
        ->with('Failed to Save Venue'. $venue);

    $venueRepo = new VenueRepository();
    $this->withExceptionHandling();
    $venueRepo->store($venue);
}
Horace answered 18/9, 2018 at 3:6 Comment(0)
K
3

Maybe you can use event listener on Models. using this you can get logs on Create or other Events. Check out the Example Below. Hope to help .

Info 1.

<?php
    namespace App;
    use Illuminate\Database\Eloquent\Model;
    use User;
    class Venue extends Model
    {
        protected $fillable = ['title', 'ect..'];
        public static function boot() {
            parent::boot();
            static::created(function($item) {
                \Log::info('venue.created');
            });
            static::updated(function($item) {
                \Log::info('venue.created');
            });
            static::deleted(function($item) {
                \Log::info('venue.created');
            });

        }

    }

Info 2.

Also there is an exists method on model

if ($venue->exists()) {
    // saved 
} else {
    // not saved
}

Info 3

To get the insert queries when $venue->save(); error, you can try to catch the exception like this:

    try{
       $venue = new Venue;
       $venue->fields = 'example';
       $venue->save(); // returns false
    }
    catch(\Exception $e){
       // do task when error
       \Log::info($e->getMessage());   // insert query
    }

Hope this helps :)

Kelliekellina answered 9/7, 2018 at 14:49 Comment(0)
S
0

I'm using the "Log fake" package to make assertions against the log channels, stacks, etc.

Using the package, you could do something like this for the example you shared:

LogFake::bind();

$venue = new Venue();
$venueRepo = new VenueRepository();
$venueRepo->store($venue);

Log::assertLogged(fn (LogEntry $log) =>
    $log->level === 'info'
    && $log->message === 'Failed to Save Venue'. $venue
);
Subtile answered 2/11, 2023 at 8:54 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.