Unittesting Laravel 5 Mail using Mock

让人想犯罪 __ 提交于 2019-12-05 11:05:30

Cost me the better part of an afternoon but this is finally what worked - I passed in a Closure and gave it a Mockery object

Code being tested:

$subject = "The subject";

Mail::send('emails.emailTemplate', ['user' => $user ], 
function( $mail ) use ($user, $subject){
    $mail   -> to( $user -> email)
            -> subject( $subject );                 
});

Test that worked:

$subject = "The subject";
$user = factory(App\Models\User::class) -> create();

Mail::shouldReceive('send') -> once() -> with(
        'emails.emailTemplate',
        m::on( function( $data ){
            $this -> assertArrayHasKey( 'user', $data );
            return true; 
        }),
        m::on( function(\Closure $closure) use ($user, $subject){
            $mock = m::mock('Illuminate\Mailer\Message');
            $mock -> shouldReceive('to') -> once() -> with( $user -> email )
                  -> andReturn( $mock ); //simulate the chaining
            $mock -> shouldReceive('subject') -> once() -> with($subject);
            $closure($mock);
            return true;
        })
    );

Just discovered from the Laravel 5 documentation that Facades are treated differently and have their own ways to be tested. Since i'm using a Mail Facade, i did a bit of experimentation from the meager info produced in the Laravel 5 documentation page. so here's the code i used

    // Mock the Mail Facade and assert that it receives a Mail::queue()
    // with [whatever info you wish to check is passed. in my case, they're error contents]
    Mail::shouldReceive('queue')->once()
        ->andReturnUsing(function($view, $view_params) {
            $this->assertNotEmpty($view_params['error_message']);
            $this->assertNotEmpty($view_params['request']);
            $this->assertNotEmpty($view_params['stack_trace']);
        });
  Mail::shouldReceive('to')->once()->with('user email')
     ->andReturnUsing( function ($errorPasedToMailable) {
       // here you are passing whatever type (array|model) to your Mailable
       // in my case this is ['errorMessage' => 'some error']
      $this->assertNotEmpty($errorPasedToMailable['errorMessage']);
       // here result is your expected error message
      $this->assertEquals($result, $errorPasedToMailable['errorMessage'])

});
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!