#symfony #symfony-mailer
#симфония #symfony-почтовая программа
Вопрос:
С помощью Mailer, по-видимому, невозможно получить текст сообщения электронной почты в ходе функционального теста. Например, с помощью
$email = $this->getMailerMessage(0);
$body = $email->getBody();
var_dump($body);
$body
раскрывается как
объект(SymfonyComponentMimePartMultipartAlternativePart)…
У этого объекта нет (очевидных) доступных свойств. Существует ли какой-либо способ доступа к тексту тела электронного письма, отправленного с помощью Symfony Mailer в функциональном тестировании?
С помощью SwiftMailer можно получить текст электронного письма в функциональном тестировании с помощью:
$mailCollector = $this->client->getProfile()->getCollector('swiftmailer');
$collectedMessages = $mailCollector->getMessages();
$message = $collectedMessages[0];
$body = $message->getBody();
Ответ №1:
Потребовалось довольно много времени, чтобы найти это. Проследил assertEmailHeaderSame
назад , чтобы найти assertEmailHtmlBodyContains
то class EmailHtmlBodyContains
, что есть $message->getHtmlBody()
.
Итак, теперь мой тест включает $body = $email->getHtmlBody();
в себя, который является строкой. Которые могут быть проанализированы.
Ответ №2:
Итак, давайте начнем. Сначала создайте МАКЕТ вашего сервиса в вашем тесте следующим образом:
$this->mailer = $this->createMock(Swift_Mailer::class);
self::$container->set('swiftmailer.mailer.default', $this->mailer);
после определения переменной массива для ваших сообщений в текущем тесте
/** @var null|Swift_Message $emailMessage */
$emailMessages = [];
$this->mailer
->method('send')
->willReturnCallback(function (Swift_Message $message) use (amp;$emailMessages) {
$emailMessages[] = $message;
});
итак, мы будем переадресовывать каждое электронное письмо в $emailMessages, вам нужно просто выбрать нужное сообщение и указать его содержимое следующим образом:
$emailMessage = $emailMessages[0] ?? null;
$this->assertNotNull($emailMessage);
$this->assertInstanceOf(Swift_Message::class, $emailMessage);
$body = $emailMessage->getBody();
$expected = file_get_contents(__DIR__ . '/../data/RestController/ServiceController/you_message_body.html');
// do not forget to replace dynamic data in the snapshot.
$body = preg_replace('/cid:[a-z0-9]{32}/ui', 'cid_here', $body);
$this->assertEquals($expected, $body);
Комментарии:
1. Я рекомендую создавать все макеты в методе setUp(), вот почему я использую свойство для МАКЕТА
2. Спасибо за ваш вклад. Пожалуйста, обратите внимание, что вопрос (и ответ) относится к Symfony Mailer, а не к SwiftMailer.
3. тот же метод, разница только в обслуживании
4. То, что вы описываете, не является функциональным тестом из-за использования MOCK .
5. это МАКЕТ в функциональном тесте, вы можете установить МАКЕТ в контейнер Symfony вместо реального сервиса. Все будет работать как обычно, но этот сервис будет МАКЕТНЫМ. Вы когда-нибудь пытались это сделать? Итак, давайте попробуем!
Ответ №3:
- Создайте services_test.yaml рядом с вашими сервисами.yaml должен выглядеть следующим образом:
services:
# default configuration for services in *this* file
_defaults:
autowire: true # Automatically injects dependencies in your services.
autoconfigure: true # Automatically registers your services as commands, event subscribers, etc.
public: true
test.mailer_symfony: '@SymfonyComponentMailerMailerInterface'
- В методе установки имитируйте реальную службу и измените ее в сервисном контейнере
use SymfonyComponentMailerMailerInterface;
// setUp()
$this->mailer = $this->createMock(MailerInterface::class);
self::$container->set('test.mailer_symfony', $this->mailer);
- Макет метода send() в вашем тесте, согласно этому коду https://github.com/symfony/mailer/blob/5.x/MailerInterface.php это должно быть что-то вроде:
use use SymfonyComponentMimeRawMessage;
// ....
/** @var RawMessage[] $emailMessages */
$emailMessages = [];
$this->mailer
->method('send')
->willReturnCallback(function (RawMessage $message, Envelope $envelope = null) use (amp;$emailMessages) {
$emailMessages[] = $message;
});
вот и все, вы можете указать $emailMessages в конце вашего теста, таким образом, вы также можете добавлять expects
и проверять количество вызовов send()
метода