在测试中,我想使用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
答案 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