获取命令测试期间发送的电子邮件内容
Get content of email sent during command tests
在测试期间,我调用了一些发送电子邮件的命令。我可以使用以下命令显示发送的电子邮件数量:
$output->writeln(
$spool->flushQueue(
$this->getContainer()->get('swiftmailer.transport.real')
)
);
Symfony2 文档解释了 how to get email content by using the profiler during a Web test(在 Stack Overflow 上也有解释),但我不知道在没有 Web 请求时如何做同样的事情。
我使用了这些链接中提供的代码:
<?php
namespace ACME\MyBundle\Tests\Command;
use Liip\FunctionalTestBundle\Test\WebTestCase;
class EmailTest extends WebTestCase
{
public function tesEmailCommand()
{
// load data fixtures
// http://symfony.com/doc/current/cookbook/email/testing.html
$client = static::createClient();
// Enable the profiler for the next request (it does nothing if the profiler is not available)
$client->enableProfiler();
/** @var \Symfony\Bundle\FrameworkBundle\Console\Application $application */
// inherit from the parent class
$application = clone $this->application;
$application->add(new EmailCommand());
$command = $application->find('acme:emails');
$commandTester = new CommandTester($command);
$commandTester->execute(array(
'command' => 'acme:emails'
));
$display = $commandTester->getDisplay();
$this->assertContains('foo', $display);
// http://symfony.com/doc/current/cookbook/email/testing.html
$mailCollector = $client->getProfile()->getCollector('swiftmailer');
// Check that an email was sent
$this->assertEquals(1, $mailCollector->getMessageCount());
$collectedMessages = $mailCollector->getMessages();
$message = $collectedMessages[0];
// Asserting email data
$this->assertInstanceOf('Swift_Message', $message);
$this->assertEquals(
'You should see me from the profiler!',
$message->getBody()
);
}
}
它returns这个错误:
Argument 1 passed to Symfony\Component\HttpKernel\Profiler\Profiler::loadProfileFromResponse() must be an instance of Symfony\Component\HttpFoundation\Response, null given, called in .../vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Client.php on line 72 and defined
.../vendor/symfony/symfony/src/Symfony/Component/HttpKernel/Profiler/Profiler.php:81
.../vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Client.php:72
.../src/ACME/MyBundle/Tests/Command/EmailTest.php:94
错误来自这一行:
$mailCollector = $client->getProfile()->getCollector('swiftmailer');
这似乎是合乎逻辑的,因为没有请求就没有响应。
我使用 Symfony 2.8.7。
这是我在 app/config_test.yml
中的 Swiftmailer 配置:
swiftmailer:
disable_delivery: true
delivery_address: %swiftmailer.delivery_address%
您可以'fake'这样的请求,这可能可以帮助您。
$this->getContainer()->enterScope('request');
$request = Request::create('http://yourdomain.com'));
$this->getContainer()->set('request', $request, 'request');
$this->getContainer()->get('router')->getContext()->setHost('http://yourdomain.com');
我有一个功能,它在我使用需要存在请求的服务的命令中执行类似操作。
您可以为 Monolog 添加自定义频道并将电子邮件内容发送到日志文件。
在config.yml中添加
monolog:
channels: ["mm"]
handlers:
mm:
level: debug
type: stream
path: "%kernel.logs_dir%/mm.log"
channels: ["mm"]
然后在命令代码中使用:
$logger = $this->get('monolog.logger.mm');
$logger->info($emailContent);
我没有找到解决方案,而是让我的命令更加冗长,以便显示解释已完成操作的消息,间接告诉我电子邮件内容是什么。
默认情况下 SwiftmailerBundle 添加消息记录器插件
$this->getContainer()
->get('swiftmailer.mailer.default.plugin.messagelogger')
->getMessages();
您可以在命令测试中使用它。
您需要将插件注册到邮件程序中:
$mailer = static::$container->get('swiftmailer.mailer');
$logger = new \Swift_Plugins_MessageLogger();
$mailer->registerPlugin( $logger );
然后你可以循环所有发送的消息并查看你需要的数据,例如:
foreach ( $logger->getMessages() as $message ) {
echo sprintf( '%s%s',$message->getSubject(), Chr(10) );
echo sprintf( '%s%s',$message->getBody(), Chr(10) );
}
这里的关键是牢记在 SwiftMail 库中,文件 MailTransport.php 调度事件 "beforeSendPerformed"。此事件由 Swift_Plugins_MessageLogger 的实例 $logger 监听。该插件实现了 Swift_Events_SendListener 接口,其中一个方法是 getMessages,其中包含发送的消息的内容。您还可以检查 swiftmail/swiftmailer 在您的 symfony 功能测试中发送的消息数。
我已经能够使用它:
// kernel
$kernel = $this->createKernel();
$kernel->boot();
// container
$container = $kernel->getContainer();
// register swiftmailer logger
$mailer = $container->get('mailer');
$logger = new \Swift_Plugins_MessageLogger();
$mailer->registerPlugin($logger);
然后您可以通过以下方式获取消息内容:
foreach ($logger->getMessages() as $message) {
$subject = $message->getSubject();
$plaintextBody = $message->getBody();
$htmlBody = $message->getChildren()[0]->getBody();
}
在测试期间,我调用了一些发送电子邮件的命令。我可以使用以下命令显示发送的电子邮件数量:
$output->writeln(
$spool->flushQueue(
$this->getContainer()->get('swiftmailer.transport.real')
)
);
Symfony2 文档解释了 how to get email content by using the profiler during a Web test(在 Stack Overflow 上也有解释),但我不知道在没有 Web 请求时如何做同样的事情。
我使用了这些链接中提供的代码:
<?php
namespace ACME\MyBundle\Tests\Command;
use Liip\FunctionalTestBundle\Test\WebTestCase;
class EmailTest extends WebTestCase
{
public function tesEmailCommand()
{
// load data fixtures
// http://symfony.com/doc/current/cookbook/email/testing.html
$client = static::createClient();
// Enable the profiler for the next request (it does nothing if the profiler is not available)
$client->enableProfiler();
/** @var \Symfony\Bundle\FrameworkBundle\Console\Application $application */
// inherit from the parent class
$application = clone $this->application;
$application->add(new EmailCommand());
$command = $application->find('acme:emails');
$commandTester = new CommandTester($command);
$commandTester->execute(array(
'command' => 'acme:emails'
));
$display = $commandTester->getDisplay();
$this->assertContains('foo', $display);
// http://symfony.com/doc/current/cookbook/email/testing.html
$mailCollector = $client->getProfile()->getCollector('swiftmailer');
// Check that an email was sent
$this->assertEquals(1, $mailCollector->getMessageCount());
$collectedMessages = $mailCollector->getMessages();
$message = $collectedMessages[0];
// Asserting email data
$this->assertInstanceOf('Swift_Message', $message);
$this->assertEquals(
'You should see me from the profiler!',
$message->getBody()
);
}
}
它returns这个错误:
Argument 1 passed to Symfony\Component\HttpKernel\Profiler\Profiler::loadProfileFromResponse() must be an instance of Symfony\Component\HttpFoundation\Response, null given, called in .../vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Client.php on line 72 and defined .../vendor/symfony/symfony/src/Symfony/Component/HttpKernel/Profiler/Profiler.php:81 .../vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Client.php:72 .../src/ACME/MyBundle/Tests/Command/EmailTest.php:94
错误来自这一行:
$mailCollector = $client->getProfile()->getCollector('swiftmailer');
这似乎是合乎逻辑的,因为没有请求就没有响应。
我使用 Symfony 2.8.7。
这是我在 app/config_test.yml
中的 Swiftmailer 配置:
swiftmailer:
disable_delivery: true
delivery_address: %swiftmailer.delivery_address%
您可以'fake'这样的请求,这可能可以帮助您。
$this->getContainer()->enterScope('request');
$request = Request::create('http://yourdomain.com'));
$this->getContainer()->set('request', $request, 'request');
$this->getContainer()->get('router')->getContext()->setHost('http://yourdomain.com');
我有一个功能,它在我使用需要存在请求的服务的命令中执行类似操作。
您可以为 Monolog 添加自定义频道并将电子邮件内容发送到日志文件。
在config.yml中添加
monolog:
channels: ["mm"]
handlers:
mm:
level: debug
type: stream
path: "%kernel.logs_dir%/mm.log"
channels: ["mm"]
然后在命令代码中使用:
$logger = $this->get('monolog.logger.mm');
$logger->info($emailContent);
我没有找到解决方案,而是让我的命令更加冗长,以便显示解释已完成操作的消息,间接告诉我电子邮件内容是什么。
默认情况下 SwiftmailerBundle 添加消息记录器插件
$this->getContainer()
->get('swiftmailer.mailer.default.plugin.messagelogger')
->getMessages();
您可以在命令测试中使用它。
您需要将插件注册到邮件程序中:
$mailer = static::$container->get('swiftmailer.mailer');
$logger = new \Swift_Plugins_MessageLogger();
$mailer->registerPlugin( $logger );
然后你可以循环所有发送的消息并查看你需要的数据,例如:
foreach ( $logger->getMessages() as $message ) {
echo sprintf( '%s%s',$message->getSubject(), Chr(10) );
echo sprintf( '%s%s',$message->getBody(), Chr(10) );
}
这里的关键是牢记在 SwiftMail 库中,文件 MailTransport.php 调度事件 "beforeSendPerformed"。此事件由 Swift_Plugins_MessageLogger 的实例 $logger 监听。该插件实现了 Swift_Events_SendListener 接口,其中一个方法是 getMessages,其中包含发送的消息的内容。您还可以检查 swiftmail/swiftmailer 在您的 symfony 功能测试中发送的消息数。
我已经能够使用它:
// kernel
$kernel = $this->createKernel();
$kernel->boot();
// container
$container = $kernel->getContainer();
// register swiftmailer logger
$mailer = $container->get('mailer');
$logger = new \Swift_Plugins_MessageLogger();
$mailer->registerPlugin($logger);
然后您可以通过以下方式获取消息内容:
foreach ($logger->getMessages() as $message) {
$subject = $message->getSubject();
$plaintextBody = $message->getBody();
$htmlBody = $message->getChildren()[0]->getBody();
}