matthiasnoback / symfony-config-test
用于测试与Symfony Config组件相关的用户类的库
Requires
- php: ^8.1
- phpunit/phpunit: ^9.6 || ^10.0 || ^11.0
- symfony/config: ^5.4 || ^6.2 || ^7.0
This package is auto-updated.
Last update: 2024-08-23 19:32:16 UTC
README
由Matthias Noback及贡献者编写
使用Symfony Config组件定义配置类可能会很困难。为了帮助您验证生成的配置节点树的有效性,此库提供了一个PHPUnit测试用例和一些自定义断言。
安装
使用Composer
composer require --dev matthiasnoback/symfony-config-test
用法
创建一个测试用例,并使用来自Matthias\SymfonyConfigTest\PhpUnit\ConfigurationTestCaseTrait
的特质。然后实现getConfiguration()
<?php use Matthias\SymfonyConfigTest\PhpUnit\ConfigurationTestCaseTrait; use PHPUnit\Framework\TestCase; use App\Configuration; class ConfigurationTest extends TestCase { use ConfigurationTestCaseTrait; protected function getConfiguration(): Configuration { return new Configuration(); } }
测试无效的配置值
假设您想测试的Configuration
类看起来像这样
<?php use Symfony\Component\Config\Definition\Builder\TreeBuilder; use Symfony\Component\Config\Definition\ConfigurationInterface; class ConfigurationWithRequiredValue implements ConfigurationInterface { public function getConfigTreeBuilder(): TreeBuilder { $treeBuilder = new TreeBuilder(); $rootNode = $treeBuilder->root('root'); $rootNode ->isRequired() ->children() ->scalarNode('required_value') ->isRequired() ->end() ->end(); return $treeBuilder; } }
当你为这个配置提供一个空数组作为值时,你会期望抛出一个异常,因为required_value
节点是必需的。你可以使用assertConfigurationIsInvalid()
方法断言一组配置值是无效的
<?php use Matthias\SymfonyConfigTest\PhpUnit\ConfigurationTestCaseTrait; use PHPUnit\Framework\TestCase; class ConfigurationTest extends TestCase { use ConfigurationTestCaseTrait; /** * @test */ public function values_are_invalid_if_required_value_is_not_provided(): void { $this->assertConfigurationIsInvalid( [ [] // no values at all ], 'required_value' // (part of) the expected exception message - optional ); } }
测试处理后的配置值
你可能还想要验证处理配置值数组后的结果是否符合预期
<?php use Matthias\SymfonyConfigTest\PhpUnit\ConfigurationTestCaseTrait; use PHPUnit\Framework\TestCase; class ConfigurationTest extends TestCase { use ConfigurationTestCaseTrait; /** * @test */ public function processed_value_contains_required_value(): void { $this->assertProcessedConfigurationEquals([ ['required_value' => 'first value'], ['required_value' => 'last value'] ], [ 'required_value'=> 'last value' ]); } }
请注意:每个assert*
方法的第一个参数都是一个数组数组。额外的嵌套级别允许你测试合并过程。请参阅配置组件文档的合并选项部分。
测试配置树的一个子集
使用这个库可以测试配置树的一个分支。考虑以下节点树定义,它包含分支array_node_1
和array_node_2
<?php use Symfony\Component\Config\Definition\Builder\TreeBuilder; use Symfony\Component\Config\Definition\ConfigurationInterface; class ConfigurationWithTwoBranches implements ConfigurationInterface { public function getConfigTreeBuilder(): TreeBuilder { $treeBuilder = new TreeBuilder(); $rootNode = $treeBuilder->root('root'); $rootNode ->children() ->arrayNode('array_node_1') ->isRequired() ->children() ->scalarNode('required_value_1') ->isRequired() ->end() ->end() ->end() ->arrayNode('array_node_2') ->isRequired() ->children() ->scalarNode('required_value_2') ->isRequired() ->end() ->end() ->end() ->end(); return $treeBuilder; } }
如果你只想测试下面的示例中的array_node_1
分支,并忽略array_node_2
,请为测试辅助函数的$breadcrumbPath
参数提供array_node_1
,例如
/** * @test */ public function processed_configuration_for_array_node_1(): void { $this->assertProcessedConfigurationEquals( [ ['array_node_1' => ['required_value_1' => 'original value']], ['array_node_1' => ['required_value_1' => 'final value']] ], [ 'array_node_1' => [ 'required_value_1' => 'final value' ] ], // the path of the nodes you want to focus on in this test: 'array_node_1' ); }
这将触发array_node_2
分支中任何值的验证错误。
请注意,$breadcrumbPath
可以更具体,例如"doctrine.orm"
(这将跳过分支"doctrine.dbal"
等的配置处理)。
请注意,你只能使用点.
在面包屑路径中遍历数组节点。面包屑路径的最后部分可以是任何其他类型的节点。
测试原型配置树的一个子集
你可以使用面包屑路径中的*
作为其名称来遍历原型数组节点。
<?php use Symfony\Component\Config\Definition\Builder\TreeBuilder; use Symfony\Component\Config\Definition\ConfigurationInterface; class PrototypedConfiguration implements ConfigurationInterface { public function getConfigTreeBuilder(): TreeBuilder { $treeBuilder = new TreeBuilder(); $rootNode = $treeBuilder->root('root'); $rootNode ->children() ->arrayNode('array_node') ->useAttributeAsKey('name') ->prototype('array') ->children() ->scalarNode('default_value')->cannotBeEmpty()->defaultValue('foobar')->end() ->scalarNode('required_value')->isRequired()->end() ->end() ->end() ->end() ->end(); return $treeBuilder; } }
如果你想测试默认情况下default_value
是否设置为foobar
,但不想测试受到required_value
节点要求的约束,你可以定义其路径为array_node.*.default_value
,例如
/** * @test */ public function processed_configuration_for_array_node_1(): void { $this->assertProcessedConfigurationEquals( [ ['array_node' => ['prototype_name' => null]], ], [ 'array_node' => [ 'prototype_name' => [ 'default_value' => 'foobar' ] ] ], // the path of the nodes you want to focus on in this test: 'array_node.*.default_value' ); }