Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Testing Symfony2 emails with Behat 3

I followed the Behat 2.5 docs to test mails. After a few tweaks to match Behat 3 I have ended with the following code (I have removed non-relevant parts):

public function getSymfonyProfile()
{
    $driver = $this->mink->getSession()->getDriver();

    if (!$driver instanceof KernelDriver) {
        // Throw exception
    }

    $profile = $driver->getClient()->getProfile();
    if (false === $profile) {
        // Throw exception
    }

    return $profile;
}

/**
 * @Then I should get an email with subject :subject on :email
 */
public function iShouldGetAnEmail($subject, $email)
{
    $profile   = $this->getSymfonyProfile();
    $collector = $profile->getCollector('swiftmailer');

    foreach ($collector->getMessages() as $message) {
        // Assert email
    }

    // Throw an error if something went wrong
}

When I run this test, it throws the following error:

exception 'LogicException' with message 'Missing default data in Symfony\Bundle\SwiftmailerBundle\DataCollector\MessageDataCollector' in vendor/symfony/swiftmailer-bundle/Symfony/Bundle/SwiftmailerBundle/DataCollector/MessageDataCollector.php:93
Stack trace:
    #0 vendor/symfony/swiftmailer-bundle/Symfony/Bundle/SwiftmailerBundle/DataCollector/MessageDataCollector.php(122): Symfony\Bundle\SwiftmailerBundle\DataCollector\MessageDataCollector->getMailerData('default')
    #1 features/bootstrap/FeatureContext.php(107): Symfony\Bundle\SwiftmailerBundle\DataCollector\MessageDataCollector->getMessages()

My profiler is configured as follows:

# app/config/config_test.yml
framework:
    test: ~
    profiler:
        enabled: true
        collect: true

It seems that the Profile is correctly loaded and the MessageDataCollector from Swiftmailer does exist, but it is not doing its work as expected. Any clue to solve this?

like image 488
albertedevigo Avatar asked Nov 21 '14 12:11

albertedevigo


2 Answers

Maybe the issue you have has been fixed as I do not have this anymore (I'm using Behat v3.0.15, BrowserKit driver 1.3.* and Symfony v2.6.6).

I managed to reproduce your error but only when I forgot to enable profiler data collecting:

profiler:
    collect: false

Once this problem solved (the configuration you provided solving the problem for me) I managed to check emails in my Behat tests. Two solutions for this:

Solution #1: Intercepting redirects globally

If it does not break all your other tests you can do so by configuring your web profiler as follows:

web_profiler:
    intercept_redirects: true

Solution #2: Preventing client to follow redirections temporarily

For my part, intercepting redirections globally in the configuration broke most of my other functional tests. I therefore use this method instead.

As preventing redirections allows mainly to check data in the data collectors I decided to use a tag @collect on each scenario requiring redirect interception. I then used @BeforeScenario and @AfterScenario to enable this behaviour only for those scenarios:

/**
 * Follow client redirection once
 *
 * @Then /^(?:|I )follow the redirection$/
 */
public function followRedirect()
{
    $this->getDriver()->getClient()->followRedirect();
}

/**
 * Restore the automatic following of redirections
 *
 * @param BeforeScenarioScope $scope
 *
 * @BeforeScenario @collect
 */
public static function disableFollowRedirects(BeforeScenarioScope $scope)
{
    $context = $scope->getEnvironment()->getContext(get_class());
    $context->getDriver()->getClient()->followRedirects(false);
}

/**
 * Restore the automatic following of redirections
 *
 * @param AfterScenarioScope $scope
 *
 * @AfterScenario @collect
 */
public static function restoreFollowRedirects(AfterScenarioScope $scope)
{
    $context = $scope->getEnvironment()->getContext(get_class());
    $context->getDriver()->getClient()->followRedirects(true);
}
like image 191
CharlyP Avatar answered Oct 18 '22 20:10

CharlyP


It's not the answer your are looking for, but I'm pretty sure it will suits your needs (perhaps more).
If I can suggest, try using Mailcatcher with this bundle: https://packagist.org/packages/alexandresalome/mailcatcher
You'll be able to easily tests if emails are sent, what's their subject, follow a link in the body, and so on...
Many steps are included with this bundle.

like image 4
Pierre Marichez Avatar answered Oct 18 '22 22:10

Pierre Marichez