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);
}
3
  • Maybe with something like if(!$saved){ $saved = 'Failed to Save Venue'. $venue; Log::info($saved); } return $saved; Commented Jul 9, 2018 at 13:20
  • Below I have answered with 3 ideas :), Hope one of them will help to solve your problem. Commented Jul 9, 2018 at 14:57
  • I do think so . May be you should try with debuging $saved instead of $venue. or do dumping $venue before saving. Commented Jul 10, 2018 at 3:04

3 Answers 3

37

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);
}
Sign up to request clarification or add additional context in comments.

Comments

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 :)

Comments

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
);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.