Как проверить тему письма с помощью laravel's Mailable
Мне интересно, есть ли простой и прямой способ проверить тему письма, используя новую функцию Mailable от Laravel
У меня есть класс, который может отправлять 5 разных писем, но все они одному и тому же человеку, поэтому проверка того, было ли отправлено письмо конкретному человеку, на самом деле не является полным тестом. Мне нужно знать, было ли отправлено конкретное электронное письмо конкретному человеку.
Я думаю, лучше всего использовать тему письма для проверки уникальности. Если у вас есть лучший способ, пожалуйста, скажите мне.
У меня есть это:
Mail:: assertSentTo ([Config:: get ('mail.backend')], SendEmail:: class);
И я хотел бы добавить что-то вроде этого
Mail::assertSubject('Моя тема', SendEmail::class);
Есть ли способ сделать это??
Спасибо!
1 ответ
редактировать
Быстрое и лучшее решение, чем мое (см. Ниже), можно найти в разделе Как сделать утверждения на Laravel Mailable, благодаря @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';
});
и это должно сработать. Правильно? Ну, это не будет, если вы не сделаете вещи немного по-другому.
ИМО источник ПРОБЛЕМЫ
В руководстве по почте каждый пример, который они представляют, использует build
метод:
public function build()
{
return $this->from('example@example.com')
->subject('The SUBJECT that I very much need')
->view('emails.orders.shipped');
}
Дело в том, что когда вы звоните Mail::fake()
в верхней части вашего метода вы превращаете всю почтовую систему в https://laravel.com/api/5.6/Illuminate/Support/Testing/Fakes/MailFake.html (вот почему она поддерживает 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';
});
Надеюсь, поможет.
PS
Я лучше сделаю что-то вроде этого, потому что чувствую, что контроль намного более детализирован:
class MailControllerTest extends TestCase
{
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
Работы в модульном тестировании никогда не пройдут в неправильном состоянии.:)
С 5.4
Чтобы выполнить тест, который у вас есть в вашем вопросе, вы должны сделать:
Mail::assertSent(SendEmail::class, function ($mail) {
return $mail->hasTo(Config::get('mail.backend'));
});
чтобы проверить, что предмет вы могли бы сделать что-то вроде:
Mail::assertSent(SendEmail::class, function ($mail) {
return $mail->hasTo(Config::get('mail.backend'))
&& $mail->subject == 'My Subject';
});
https://laravel.com/docs/5.4/mocking
Надеюсь это поможет!
Примечание: Моя версия Laravel: 6.x
Вам нужно позвонить build()
перед утверждением темы. Здесь я утверждаю, что электронное письмо отправлено аутентифицированным пользователям, и тема - Уведомление о платеже.
Mail::assertQueued(DepositePaymentMail::class, function ($mail) {
$mail->build();
return $mail->hasTo(auth()->user()->email) &&
$mail->subject == 'Payment Deposit Notification';
});
и моя функция сборки класса Mailable выглядит так:
public function build()
{
return $this->subject('Payment Deposit Notification')
->markdown(
'email.company.deposite-payment-request'
);
}