Symfony2: 如何测试配置节点的值和索引

8
在Symfony2中,使用此类设置,我如何测试每个节点是否在Configuration类中定义,并且它们的值是否正确配置。 测试用的类: ```php # My\Bundle\DependencyInjection\Configuration.php class Configuration implements ConfigurationInterface { /** * {@inheritDoc} */ public function getConfigTreeBuilder() { $treeBuilder = new TreeBuilder(); $treeBuilder->root('my_bundle') ->children() ->scalarNode("scalar")->defaultValue("defaultValue")->end() ->arrayNode("arrayNode") ->children() ->scalarNode("val1")->defaultValue("defaultValue1")->end() ->scalarNode("val2")->defaultValue("defaultValue2")->end() ->end() ->end() ->end() ;
return $treeBuilder; } } ``` 这是我想要在单元测试中执行的断言: 我尝试将节点作为数组访问,但似乎不起作用。 此外,TreeBuilder 似乎不会给我们以获取配置作为数组的可能性,除非它们由bundle extension加载。   测试代码: ```php # My\Bundle\Tests\DependencyInjection\ConfigurationTest.php $configuration = $this->getConfiguration(); $treeBuilder = $configuration->getConfigTreeBuilder(); $this->assertInstanceOf("Symfony\Component\Config\Definition\Builder\TreeBuilder", $treeBuilder);
// 如何访问树构建器的节点? $rootNode = $treeBuilder["my_bundle"]; $scalarNode = $treeBuilder["scalar"]; $arrayNode = $treeBuilder["arrayNode"]; $val1Node = $arrayNode["val1"]; $val2Node = $arrayNode["val2"]; $this->assertInstanceOf("Symfony\...\ArrayNodeDefinition", $rootNode); $this->assertEquals("defaultValue", $scalarNode, "测试节点的默认值"); $this->assertEquals("defaultValue", $val1Node, "测试节点的默认值"); $this->assertEquals("defaultValue", $val2Node, "测试节点的默认值"); ```

我不认为通过测试配置的方式去测试它是一种好主意。 - Ziumin
@Ziumin,您会建议采用哪种方法来确保值已设置默认值,或者应该配置默认服务ID... - yvoyer
我建议准备一组配置测试集,并使用您的Configuration类检查它们是否被正确处理。 - Ziumin
@Ziumin,我的回答是否也是正确的方式。因为我唯一看到的问题是测试依赖于另一个组件,而不仅仅是测试“Configuration”类。 - yvoyer
2个回答

11

我找到了一种解决方案,可以基于JMSSecurityBundle

与其测试配置文件,我测试将添加配置的扩展,这样就能够涵盖配置。这样,我可以断言已经设置了默认配置。

例如,这个Extension

#My\Bundle\DependencyInjection\MyBundleExtension
class MyBundleExtension extends Extension
{
    /**
     * {@inheritDoc}
     */
    public function load(array $configs, ContainerBuilder $container)
    {
        $configuration = new Configuration();
        $config        = $this->processConfiguration($configuration, $configs);

        $container->setParameter("crak_landing_frontend.scalar", $config["scalar"]);
        $container->setParameter("crak_landing_frontend.array_node", $config["array_node"]);

        $loader = new Loader\XmlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config'));
        $loader->load('services.xml');
    }
}

可能是这样的测试:

#My\Bundle\Tests\DependencyInjection\MyBundleExtensionTest
class MyBundleExtensionTest extends \PHPUnit_Framework_TestCase
{
    /**
     * @var MyBundleExtension
     */
    private $extension;

    /**
     * Root name of the configuration
     *
     * @var string
     */
    private $root;

    public function setUp()
    {
        parent::setUp();

        $this->extension = $this->getExtension();
        $this->root      = "my_bundle";
    }

    public function testGetConfigWithDefaultValues()
    {
        $this->extension->load(array(), $container = $this->getContainer());

        $this->assertTrue($container->hasParameter($this->root . ".scalar"));
        $this->assertEquals("defaultValue", $container->getParameter($this->root . ".scalar"));

        $expected = array(
            "val1" => "defaultValue1",
            "val2" => "defaultValue2",
        );
        $this->assertTrue($container->hasParameter($this->root . ".array_node"));
        $this->assertEquals($expected, $container->getParameter($this->root . ".array_node"));
    }

    public function testGetConfigWithOverrideValues()
    {
        $configs = array(
            "scalar"     => "scalarValue",
            "array_node" => array(
                "val1" => "array_value_1",
                "val2" => "array_value_2",
            ),
        );

        $this->extension->load(array($configs), $container = $this->getContainer());

        $this->assertTrue($container->hasParameter($this->root . ".scalar"));
        $this->assertEquals("scalarValue", $container->getParameter($this->root . ".scalar"));

        $expected = array(
            "val1" => "array_value_1",
            "val2" => "array_value_2",
        );
        $this->assertTrue($container->hasParameter($this->root . ".array_node"));
        $this->assertEquals($expected, $container->getParameter($this->root . ".array_node"));
    }

    /**
     * @return MyBundleExtension
     */
    protected function getExtension()
    {
        return new MyBundleExtension();
    }

    /**
     * @return ContainerBuilder
     */
    private function getContainer()
    {
        $container = new ContainerBuilder();

        return $container;
    }
}

4

为了在隔离环境中测试您的配置,您可以执行以下操作:

use Foo\YourBundle\DependencyInjection\Configuration;
use PHPUnit\Framework\TestCase;

class ConfigurationTest extends TestCase
{
    /**
     * @dataProvider dataTestConfiguration
     *
     * @param mixed $inputConfig
     * @param mixed $expectedConfig
     */
    public function testConfiguration($inputConfig, $expectedConfig)
    {
        $configuration = new Configuration();

        $node = $configuration->getConfigTreeBuilder()
            ->buildTree();
        $normalizedConfig = $node->normalize($inputConfig);
        $finalizedConfig = $node->finalize($normalizedConfig);

        $this->assertEquals($expectedConfig, $finalizedConfig);
    }

    public function dataTestConfiguration()
    {
        return [
            'test configuration'   => [
                ['input'],
                ['expected_config']
            ],
            // ...
        ];
    }
}

感谢您提供这个很棒的示例。 - Julien Bourdeau

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接