lundi 29 février 2016

Swiftmailer not sending mail on Symfony2 service test

I am having trouble on testing Symfony services that send notification emails.

In my NotificationService I have a function that persists the notification into the database and sends a notification email using a simple MailHelper class:

public function saveNewNotificationUser($newnotificationuser){
    // Get necessary repositories
    $doctrine = $this->getDoctrine();
    $repo_user = $doctrine->getRepository('AppBundle:User');
    $em = $doctrine->getManager();

    $notificationuser = $this->getNotificationUserById($newnotificationuser['idnotificationuser']);
    $user = $repo_user->findOneByIduser($newnotificationuser['iduser']);
    $notification = $this->getNotificationById($newnotificationuser['idnotification']);

    if ($notification && $user){
        // Persist on database
        $notificationuser->setDate(new \DateTime("now"));
        $notificationuser->setRead(0);
        $notificationuser->setUseruser($user);
        $notificationuser->setVariables($newnotificationuser['variables']);
        $notificationuser->setNotificationnotification($notification);
        $em->persist($notificationuser);
        $em->flush();
        // Send notification email
        // Generate notification structure
        $not = $this->createNotificationStructure($newnotificationuser['idnotification'],$newnotificationuser['variables']);
        // Define user's dafault language and send notification email
        $languagecode = $user->getLanguagelanguage()->getCode();
        $mailTo = $user->getEmail();

        // Get notification next on user's default language
        $text = $not["languages"][$languagecode]["language"];

        $this->get('mailHelper')->sendMail("notification",$mailTo,array('body' => $text["description"]), $text["title"]);

        return $notificationuser->getIdnotificationUser();
    }else{
        return false;
    }
}

When I test the function, the database insert in done correctly but the email is never sent. Here is my test class:

private $container;
private $em;

public function setUp()
{
    self::bootKernel();

    $this->container = self::$kernel->getContainer();
    $this->em = $this->container->get('doctrine')
        ->getManager();
}

public function testSaveNewNotificationUser()
{

    $notificationService = $this->container->get('notificationService');
    $newnotificationuser = array(
        'idnotificationuser' => '99',
        'iduser' => '69',
        'idnotification' => '1',
        'variables' => '32;12'
        );

    $id = $notificationService->saveNewNotificationUser($newnotificationuser);

    $item = $this->em
    ->getRepository('AppBundle:NotificationUser')
    ->findByIdnotificationUser($id);

    $this->assertCount(1, $item);
}

protected function tearDown()
{
    parent::tearDown();
    $this->em->close();
}

public function testNotificationAction()
{
    $client = static::createClient();

    $crawler = $client->request('GET', '/api/login/testnotif');

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

    // Check that an email was sent
    $this->assertEquals(1, $mailCollector->getMessageCount());
    $this->assertTrue($client->getResponse()->isSuccessful());
}

However, if I call SaveNewNotificationUser within a Controller Action, using the same "fake" data as used in testSaveNewNotificationUser, the email is sent (when disable_delivery set to false) and I can catch it via the mailCollector.

Am I missing anything? Am I taking a wrong approach to build the tests?

Aucun commentaire:

Enregistrer un commentaire