Receive email content sent during team tests

During my tests, I invoke several commands that 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 using the profiler during a web test (also explained here in the Stack Overflow section), but I don't know how to do the same 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, 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 occurs from this line:

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

It seems logical, because there is no answer, since there is no request.

I am using Symfony 2.8.7.


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

 swiftmailer: disable_delivery: true delivery_address: %swiftmailer.delivery_address% 
+5
source share
6 answers

I managed to get it to work 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 contents of the message with:

 foreach ($logger->getMessages() as $message) { $subject = $message->getSubject(); $plaintextBody = $message->getBody(); $htmlBody = $message->getChildren()[0]->getBody(); } 
+6
source

I did not find a solution, instead I made my team more verbose to display messages explaining what was done, which indirectly suggests what the contents of the email are.

+1
source

You need to register the plugin in your inbox:

 $mailer = static::$container->get('swiftmailer.mailer'); $logger = new \Swift_Plugins_MessageLogger(); $mailer->registerPlugin( $logger ); 

Then you can encode all sent messages and check the data you need, for example:

 foreach ( $logger->getMessages() as $message ) { echo sprintf( '%s%s',$message->getSubject(), Chr(10) ); echo sprintf( '%s%s',$message->getBody(), Chr(10) ); } 

The key point here is that in the SwiftMail library, the MailTransport.php file dispatches the "beforeSendPerformed" event. This event is heard by $ logger, an instance of Swift_Plugins_MessageLogger. The plugin implements the Swift_Events_SendListener interface, one of the methods is getMessages, which contains the content of sent messages. You can also check the number of swiftmail / swiftmailer messages sent in the symfony functional test.

0
source

You can "fake" such a request, this can help you.

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

I have a function that is similar in commands where I use services in which the request should be present.

-1
source

You can add a custom channel for the Monologue and send the email file to the log file.

In config.yml add

 monolog: channels: ["mm"] handlers: mm: level: debug type: stream path: "%kernel.logs_dir%/mm.log" channels: ["mm"] 

and then in the command code use:

 $logger = $this->get('monolog.logger.mm'); $logger->info($emailContent); 
-1
source

By default, SwiftmailerBundle adds a message log plugin

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

You can use it in command tests.

-1
source

All Articles