使用Behat 3测试Symfony2电子邮件

时间:2014-11-21 12:06:51

标签: symfony swiftmailer behat

我跟着Behat 2.5 docs来测试邮件。经过几次调整以匹配Behat 3后,我结束了以下代码(我删除了不相关的部分):

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
}

当我运行此测试时,会引发以下错误

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()

我的探查器配置如下:

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

似乎Profile已正确加载,而MessageDataCollector中的Swiftmailer确实存在,但它没有按预期执行。 解决这个问题的任何线索?

2 个答案:

答案 0 :(得分:4)

这不是您正在寻找的答案,但我非常确定它会满足您的需求(可能更多)。
如果我可以建议,请尝试使用此捆绑包的Mailcatcher:https://packagist.org/packages/alexandresalome/mailcatcher
您可以轻松测试是否发送了电子邮件,他们的主题是什么,跟踪正文中的链接等等...
此捆绑包中包含许多步骤。

答案 1 :(得分:4)

也许你已经解决了这个问题,因为我已经没有了这个问题(我使用Behat v3.0.15,BrowserKit驱动程序1.3。*和Symfony v2.6.6)。

我设法重现了您的错误,但只有在我忘记启用探查器数据收集时才会重现:

profiler:
    collect: false

一旦这个问题解决了(你为我解决了问题所提供的配置),我设法检查了Behat测试中的电子邮件。 两个解决方案:

解决方案#1:全局拦截重定向

如果它没有破坏您的所有其他测试,您可以通过如下配置您的Web分析器来执行此操作:

web_profiler:
    intercept_redirects: true

解决方案#2:阻止客户暂时关注重定向

就我而言,在配置中全局拦截重定向打破了我的大多数其他功能测试。因此,我改用了这种方法。

由于防止重定向主要允许检查数据收集器中的数据,因此我决定在需要重定向拦截的每个场景中使用标记@collect。然后,我使用@BeforeScenario@AfterScenario仅针对这些情况启用此行为:

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