2

I am writing tests for a small Symfony 6 project. The project contains a custom class representing a web form request. The class has methods for sending various emails using the Symfony MailerInterface. For example:

public function sendConfirmationEmail(): array
{
    if (!$this->validated) {
        return [
            'success' => false,
            'message' => 'Inquiry has not been validated. Use Inquiry->validate() first',
        ];
    }

    if (!$this->email) {
        return [
            'success' => false,
            'message' => 'Benutzer hat keine Emailadresse angegeben'
        ];
    }
    $email = (new TemplatedEmail())
        ->to($this->email)
        ->subject('Eingangsbestätigung')
        ->htmlTemplate('confirmationEmail.html.twig')
        ->textTemplate('confirmationEmail.txt.twig')
        ->context([
            'name' => $this->name,
            'mail' => $this->email,
            'phone' => $this->phone,
            'subject' => $this->subject,
            'message' => $this->message,
        ]);

    try {
        $this->mailer->send($email);
        $this->logger->debug('Confirmation mail sent');

        return [
            'success' => true,
            'message' => 'Email wurde gesendet',
        ];
    } catch (TransportExceptionInterface $e) {
        $this->logger->debug('Error sending confirmation email: ' . $e);

        return [
            'success' => false,
            'message' => 'Email konnte nicht gesendet werden: ' . $e,
        ];
    }
}

The mailer is passed to the constructor of the class as a read only variable:

public function __construct(
    private readonly LoggerInterface $logger,
    private readonly MailerInterface $mailer,
    private readonly array $officeRecipients,
    private readonly ValidatorInterface $validator,
) {
}

I have no trouble testing the successful cases using the Symfony KernelTestCase class, but I also want to test the catch block of the method in a unit test.

How can I simulate the TransportException during testing to trigger the catch block?

thorndeux
  • 307
  • 2
  • 9
  • 1
    It seems to me that you can simulate this with a string that does not correspond to the standard e-mail format. Example : `test@123`. In my memory this generates a `TransportException`. – vinceAmstoutz Jun 30 '22 at 12:54
  • @vinceAmstoutz Thanks for your comment. Unfortunately, it seems as though I have backed myself into a corner here: the method only reaches the catch block if the Inquiry has been validated (using the ValidatorInterface). But validation does not accept non-standard email addresses, so it would fail. I was thinking I could mock a custom MailerInterface for testing, which always throws a TransportException, but then I would have to relax the readonly requirement in the constructor. – thorndeux Jun 30 '22 at 12:58
  • Damn ... I hope for you that someone will have something to test. Good continuation ! :) – vinceAmstoutz Jun 30 '22 at 13:00

0 Answers0