Behat 3 - 如何在上下文中检索自定义扩展

时间:2014-10-07 11:22:29

标签: php symfony behat

我需要在上下文中添加,然后从behat.yml文件中检索额外的选项/配置。

Behat不允许我在behat.yml文件中添加一些随机参数,所以我创建了新的自定义扩展。这个扩展允许我传递特定的配置值

extensions:
    App\Behat\DevToolsExtension:
        api_url: "https://api.example.com"

所以现在behat并没有抱怨behat.yml文件中的新配置。

现在我被卡住了。如何在运行时从我的扩展中检索此配置?

我在公共功能加载(ContainerBuilder $ container,array $ config)方法中设置扩展中的现有参数,如下所示:

$container->setParameter($configKey . $key, $config[$key]);

同样,有没有办法在Context中检索这个ContainerBuilder对象或DevToolsExtension对象?

修改

解决方案是创建服务容器并将行为传递给ContainerBuilder,如下所示:

class AppExtension implements ExtensionInterface
{
    // ...
    public function load(ContainerBuilder $container, array $config)
    {
        $configKey = $this->getConfigKey() . '.';

        foreach ($this->keys as $key) {
            $keyValue = $configKey . $key;
            $container->setParameter($keyValue, $config[$key]);
        }

        $this->getServiceLocator()->setBehatContainer($container);
    }

然后使用服务定位器检索配置参数

$value = $this->getBehatContainer()->getParameter($key);

2 个答案:

答案 0 :(得分:3)

我遇到了这个问题并为项目解决了这个问题:CLIPBOARD

当然,在~v3.0上工作 可能正在研究v2.5。

在Exntesion类中,在创建扩展后,您需要初始化程序来初始化系统中的任何上下文。为此,您需要使用ContextExtension :: INITIALIZER_TAG在容器中创建服务并依赖于配置。我有

$container->setParameter('dev_tools_extension.parameters', $config); 

然后

private function loadContextInitializer(ContainerBuilder $container)
{
    $definition = new Definition(
        'App\Behat\DevToolsExtension\Context\Initializer\DevToolsExtensionInitializer', array(
            '%dev_tools_extension.parameters%'
        )
    );
    $definition->addTag(ContextExtension::INITIALIZER_TAG, array('priority' => 0));
    $container->setDefinition('dev_tools_extension.context_initializer', $definition);
}

Initializer实现Behat \ Behat \ Context \ Initializer \ ContextInitializer并调用Context。接下来,您将创建(例如Interface)并在上下文中调用函数。我有:

    /**
 * Initializes provided context.
 *
 * @param Context $context
 */
public function initializeContext(Context $context)
{
    if (!$context instanceof ClipboardContextInterface) {
        return;
    }
    /** @var ClipboardContextInterface $context */

    $context->setClipboard($this->clipboard);
}

答案 1 :(得分:1)

这是一个很好的问题。基本上下文没有返回顶部的引用,因此您无法从那里真正找到加载的扩展。扩展程序已初始化并挂钩到内部事件系统中。当上下文初始化时,它们会得到通知,并可以将必要的参数传递给它们。知道这一点,你可以创建一个适当的扩展,挂钩到Behat事件系统并将配置传递到你的上下文 - 这将是这样做的方式。

Mink扩展就是一个很好的例子,你可能找不到任何文档,但你可以在你的一个(Mink)上下文中创建一个构造函数,在那里添加一个断点并按照跟踪来找出整件事都有效。

但是......在大多数情况下,这将是一种过度杀伤力。使用可以从上下文加载的外部配置文件或通过将参数传递给上下文(与现在使用扩展名相同的方式)可以(并且应该)实现相同的功能。如果您有许多需要该配置的上下文,则最后一个选项可能无法正常工作。