如何在Laravel Mailable上进行断言

时间:2018-01-17 10:21:05

标签: php laravel phpunit laravel-5.5

在测试中,我想使用Mail::assertSent()在Mailable上做一些断言,如下所示:

Mail::assertSent(MyMailable::class, function ($mail) use ($user) {
    return $mail->hasTo($user->email);
});

到目前为止,我发现hasTo()hasFrom()hasBcc()以及所有其他has*()方法效果很好。但是,当在Mailable上声明特定属性时,例如subject该属性显示为null并且断言失败:

Mail::assertSent(MyMailable::class, function ($mail) {
    return $mail->subject === 'My Subject';
});

我相信这是因为我已经在build()方法中配置了所有Mailable属性,这些属性在断言阶段可能还没有被调用,因此尚未在对象上设置属性

我认为使用build()方法是基于文档的正确方法:

  

所有可邮寄的课程'配置在构建方法中完成。在此方法中,您可以调用各种方法,例如from,subject,view和attach来配置电子邮件的演示和传递。

https://laravel.com/docs/5.5/mail#writing-mailables

我发现当我在构造函数上设置属性时,我可以对Mailable的属性进行断言:

class MyMail extends Mailable
{
    public function __construct()
    {
        $this->subject = 'My Subject';
    }

    public function build() {
        return $this->subject('My Subject')->view('emails/my-email')
    }
}

但是,我觉得这种方法是错误的,因为我觉得我正在改变我的代码以适合我的测试。

所以,我想知道是否有更好的方法来对Mailable上的属性进行断言?非常感谢任何帮助,谢谢!

编辑1

测试类(无关代码被剥离)

/** @test */
function a_notification_is_sent_when_an_application_is_updated()
{
    Mail::fake([RequiresVerification::class]);

    // some set up and factory methods called here...

    // the listener for this event sends mail
    ApplicationUpdated::dispatch($application);

    // this assertion passes
    Mail::assertSent(RequiresVerification::class);

    // this assertion does not pass when subject is set on the build()  
    // method but passes when subject is set on the constructor
    Mail::assertSent(RequiresVerification::class, function ($mail) use ($user) {
        return $mail->subject === 'hello';
    });
}

编辑2

我目前正在查看所有has*方法使用的hasRecipient() method,以了解它如何处理针对我假设的Mailable属性(to,from,bcc,cc等)的断言。也许可以使用类似的方法扩展Mailable对象以添加新的属性断言?

https://github.com/laravel/framework/blob/5.5/src/Illuminate/Mail/Mailable.php#L540

1 个答案:

答案 0 :(得分:2)

在进行断言之前,您可以通过在build()闭包内调用build()方法对assertSent方法中配置的属性进行断言:

Mail::assertSent(MyMailable::class, function ($mail) {
    $mail->build();
    return $mail->subject === 'My Subject';
});

感谢@ohffs对laracasts的帮助:https://laracasts.com/discuss/channels/testing/how-to-make-assertions-on-a-laravel-mailable