编辑
感谢@haakym _
build()
只需在断言之前调用该方法:
Mail::assertSent(OrderShipped::class, function ($mail) use ($user) {
$mail->build();
return $mail->subject = 'The SUBJECT that I very much need';
});
任何我仍然喜欢的方式
Mail::assertSent(InfoRequestMailable::class, function ($mail) {
$mail->build();
$this->assertEquals(env('MOREINFO_MAILBOX'), $mail->to[0]['address'], 'The message wasn\'t send to the right email');
$this->assertEquals('Quite a subject', $mail->subject, 'The subject was not the right one');
return true;
});
我的原帖
我看到这个问题已经存在了一段时间,但我偶然发现了同样的事情。
(重要:所有这些都是为了测试一封邮件)。
使用 Laravel 5.6
在关于模拟邮件的文档中,您可以看到:
use Illuminate\Support\Facades\Mail;
class ExampleTest extends TestCase
{
public function testOrderShipping()
{
Mail::fake();
// Perform order shipping...
// Assert a message was sent to the given users...
Mail::assertSent(OrderShipped::class, function ($mail) use ($user) {
return $mail->hasTo($user->email) &&
$mail->hasCc('...') &&
$mail->hasBcc('...');
});
}
}
这将简化任何解决方案,对吗?您应该能够执行以下操作:
Mail::assertSent(OrderShipped::class, function ($mail) use ($user) {
return $mail->subject = 'The SUBJECT that I very much need';
});
这应该有效。正确的?好吧,除非你做一些不同的事情,否则它不会。
IMO问题的根源
在邮件指南中,他们提供的每个示例都使用以下build
方法:
public function build()
{
return $this->from('example@example.com')
->subject('The SUBJECT that I very much need')
->view('emails.orders.shipped');
}
问题是,当您Mail::fake()
在方法的顶部调用时,您会将整个邮件系统变成Illuminate\Support\Testing\Fakes\MailFake(这就是它支持该assertSent
方法的原因),这意味着自定义build
函数永远不会得到叫。
解决方案
您应该开始更多地使用__constructor
Mailable 类的方法。只需在方法中返回实例build()
:
遵循(并修改)邮件指南中的视图示例:
namespace App\Mail;
use Illuminate\Mail\Mailable;
class OrderShipped extends Mailable
{
...
/**
* Create a new message instance.
*
* @return void
*/
public function __construct(Order $order)
{
$this->order = $order;
$this->view('emails.orders.shipped');
$this->subject('The SUBJECT that I very much need');
}
/**
* Build the message.
*
* @return $this
*/
public function build()
{
return $this;
}
}
话虽这么说,现在这有效:
Mail::fake();
...
Mail::assertSent(OrderShipped::class, function ($mail) use ($user) {
return $mail->subject == 'The SUBJECT that I very much need';
});
附言
我宁愿做这样的事情,因为我觉得控制更加细化:
class MailControllerTest extends oTestCase
{
public function testMoreInfo()
{
Mail::fake();
// send the mail
Mail::assertSent(InfoRequestMailable::class, function ($mail) {
$this->assertEquals(env('MOREINFO_MAILBOX'), $mail->to[0]['address'], 'The message wasn\'t send to the right email');
$this->assertEquals('Quite a subject', $mail->subject, 'The subject was not the right one');
return true;
});
}
}
单元测试的工作方式assert
永远不会出错。:)