获取命令测试期间发送的电子邮件内容

时间:2015-07-28 14:08:24

标签: symfony email testing swiftmailer liipfunctionaltestbundle

在我的测试中,我调用了一些发送电子邮件的命令。我可以使用以下命令显示发送的电子邮件数量:

$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()
        );
    }
}

它返回此错误:

  

传递给Symfony \ Component \ HttpKernel \ Profiler \ Profiler :: loadProfileFromResponse()的参数1必须是Symfony \ Component \ HttpFoundation \ Response的实例,null给定,在... / vendor / symfony / symfony / src中调用/Symfony/Bundle/FrameworkBundle/Client.php在第72行并定义    ... /供应商/ symfony中/ symfony中/ src目录/ Symfony的/分量/ HttpKernel /探查/ Profiler.php:81    ... /供应商/ symfony的/ symfony的/ SRC / Symfony的/捆绑/ FrameworkBundle / Client.php:72    ... / SRC / ACME / MyBundle /测试/命令/ 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%

6 个答案:

答案 0 :(得分:9)

我已经能够使用它了:

// 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();
}

答案 1 :(得分:1)

我没有找到解决方案,而是让我的命令更加冗长,以便显示解释已完成内容的消息,这些消息间接地告诉我什么是电子邮件内容。

答案 2 :(得分:0)

您需要将插件注册到邮件程序中:

$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”。 $ logger,Swift_Plugins_MessageLogger实例监听此事件。该插件实现了Swift_Events_SendListener接口,其中一个方法是getMessages,它包含发送的消息的内容。您还可以检查symfony功能测试中发送的swiftmail / swiftmailer消息数。

答案 3 :(得分:-1)

你可以假装&#39;像这样的请求,这个可能会帮助你。

$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');

我有一个函数在命令中执行类似的操作,其中我使用需要请求的服务。

答案 4 :(得分:-1)

您可以为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);

答案 5 :(得分:-1)

默认情况下,SwiftmailerBundle添加消息记录器插件

$this->getContainer()
    ->get('swiftmailer.mailer.default.plugin.messagelogger')
    ->getMessages();

您可以在命令测试中使用它。