Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get content of email sent during command tests

During my tests I call some commands which send emails. I can display the number of emails sent with the following command:

$output->writeln(
    $spool->flushQueue(
        $this->getContainer()->get('swiftmailer.transport.real')
    )
);

The Symfony2 documentation explains how to get email content by using the profiler during a Web test (also explained here on Stack Overflow), but I don't know how to do the same thing when there is no Web request.

I used the code provided in these links:

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

It returns this error:

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

The error comes from this line:

$mailCollector = $client->getProfile()->getCollector('swiftmailer');

It seems logical because there is no response since there's no request.

I use Symfony 2.8.7.


Here is my Swiftmailer configuration in app/config_test.yml:

swiftmailer:
    disable_delivery: true
    delivery_address: %swiftmailer.delivery_address%
like image 811
A.L Avatar asked Jul 28 '15 14:07

A.L


Video Answer


1 Answers

I've been able to get it working with:

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

And then you can get the message contents with:

foreach ($logger->getMessages() as $message) {
    $subject       = $message->getSubject();
    $plaintextBody = $message->getBody();
    $htmlBody      = $message->getChildren()[0]->getBody();
}
like image 61
Boschman Avatar answered Oct 13 '22 20:10

Boschman