Как сделать утверждения на Laravel Mailable

В тесте я хотел бы сделать некоторые утверждения на Mailable с помощью Mail::assertSent(), как это:

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

До сих пор я нашел hasTo(), hasFrom(), hasBcc() и все остальные has*() методы работают просто замечательно. Однако при утверждении определенного атрибута в Mailable, например, существует subject атрибут отображается как ноль, и утверждение не выполняется:

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

Я считаю, что это потому, что я настроил все атрибуты Mailable в пределах build() метод, который на этапе утверждения, вероятно, еще не был вызван, поэтому атрибуты еще не установлены для объекта.

Я думал, используя build() Метод был правильным подходом на основе документов:

Вся конфигурация почтового класса выполняется в методе сборки. В рамках этого метода вы можете вызывать различные методы, такие как from, subject, view и attach, для настройки представления и доставки электронной почты.

https://laravel.com/docs/5.5/mail

Я обнаружил, что могу получить утверждения на атрибуты 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

Я сейчас смотрю на hasRecipient() метод, который все has* использование методов, чтобы увидеть, как он обрабатывает создание утверждений, которые, как я полагаю, являются атрибутами Mailable (to, from, bcc, cc и т. д.). Возможно, объект Mailable можно расширить для добавления новых утверждений атрибутов, используя аналогичный подход?

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

1 ответ

Вы можете сделать утверждения против атрибутов, настроенных в 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

Другие вопросы по тегам