'how to test if mailable fails in laravel?

I am testing my laravel app, I am checking it with code coverage, so, everything is working fine except this line:

<?php

namespace App\Mail;

use App\Models\Post;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Mail\Mailable;
use Illuminate\Queue\SerializesModels;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\URL;
use Throwable;

class PostCreated extends Mailable
{
    use Queueable, SerializesModels;

    protected $post;

    /**
     * Create a new message instance.
     *
     * @return void
     */
    public function __construct(Post $post)
    {
        $this->post = $post;  
    }    

    /**
     * Build the message.
     *
     * @return $this
     */
    public function build()
    {                                    

        return $this->subject('Subject')
            ->from(config('mail.from.address'))
            ->to($this->post->user->email)
            ->markdown('emails.posts.created', $this->post);
    }  
    
    /**
     * Handle a job failure.
     *
     * @param  \Throwable  $exception
     * @return void
     */
    public function failed(Throwable $exception)
    {
        //I will add this to a database logs later, but for the moment I just want to log it
        Log::error('Send email to this user was no possible '.
            $this->post->user->email
        );        
    }
}

The code coverage report shows the failed method was not tested, I am trying to test it but I can't, I suppose that I need to make the PostCreated mailable fails in my test, but I don't know how. thanks.

EDIT 1:

PostTest.php

public function test_a_it_throws_if_can_not_send_email()
    {                            

        $this->expectException(\Throwable::class);

        $listing = Post::factory()->create(); 
        
        $mailable = new PostCreated($post);
        $message = $mailable->failed(new Throwable('error sending email'));

    } 

This test pass, but when the code coverage reports still shows that it needs to be tested. So I modified the test and the code:

PostCreated.php

...
   ...
    public function failed(Throwable $exception)
    {
        
    Log::error('Send email to this user was no possible '.
        $this->post->user->email
    ); 
    //new 
    return $exception->getMessage();
    }

PostTest.php

public function test_a_it_throws_if_can_not_send_email()
{ 
  $listing = Post::factory()->create();         
  $mailable = new PostCreated($listing, 300);
        
  $message = $mailable->failed(new \Exception('error sending email'));

  $this->assertEquals($message, 'error sending email');
}

This test passes and code coverage reports is ok now, I don't know if this is the best approach but it works, maybe if you have something better let me know. thanks.



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source