有没有人有好的方法在Symfony2中对实体的验证约束进行单元测试?
理想情况下,我希望能够访问单元测试中的依赖注入容器,给予我就可以访问验证器服务。一旦我有了验证器服务,我就可以手动运行它:
$errors = $validator->validate($entity);
我可以扩展WebTestCase
,然后创建一个client
来访问文档中的容器,但是感觉不太对。WebTestCase
和client
在文档中读取时更多的是作为一个工具来测试操作整体,因此使用它来单元测试实体感觉很糟糕。
那么,有人知道如何a)获取容器或B)在单元测试中创建验证器吗?
8条答案
按热度按时间pw9qyyiw1#
好吧,既然这得到了两票,我想其他人也感兴趣。
我决定把铲子拿出来,惊喜地发现(至少到目前为止)这一点也不难完成。
我记得每个Symfony2组件都可以在独立模式下使用,因此我可以自己创建验证器。
查看以下文件:https://github.com/symfony/Validator/blob/master/ValidatorFactory.php
我意识到,既然有一个ValidatorFactory,那么创建一个验证器就很简单了(特别是对于由注解完成的验证,我就是这样,尽管如果你看看我上面链接的页面上的docblock,你也会发现验证xml和yml的方法)。
第一:
然后:
我希望这能帮助那些良心不允许只使用WebTestCase的人;).
rseugnpd2#
最后,我们滚动您自己的基本测试用例,以便从测试用例中访问依赖项容器。
有了这个基类,您现在可以在测试方法中访问验证器服务:
我们决定使用静态函数而不是类构造函数,但是您可以轻松地更改行为,将内核直接示例化到构造函数中,而不是依赖PHPUnit提供的静态方法
setUpBeforeClass
。另外,请记住,测试用例中的每个测试方法不会彼此隔离,因为容器是为整个测试用例共享的。对容器进行修改可能会影响其他测试方法,但如果您只访问
validator
服务,则不应出现这种情况。然而,通过这种方式,测试用例将运行得更快,因为您不需要为每个测试方法示例化和引导新内核。为了便于参考,我们从这个blog post中找到了这个类的灵感。它是用法语写的,但我更愿意把它的功劳归于谁:)
此致,
马特
bttbmeg03#
我喜欢Kasheens的回答,但它不再适用于Symfony 2.3。
以及
例如,如果您想验证注解,请使用enableAnnotationMapping(),如下所示:
剩下的都一样
watbbzwu4#
在Symfony 2.8中,您现在似乎可以这样使用
AbstractConstraintValidatorTest
类:您已经获得了IpValidatorTest class的良好示例
pxiryf3j5#
对于Symfony 4,https://stackoverflow.com/a/41884661/4560833中的答案必须稍微更改:
使用
ConstraintValidatorTestCase
代替AbstractConstraintValidatorTest
。6ojccjat6#
答案(B):在单元测试(Symfony 2.0)中创建验证程序
如果构建了
Constraint
和ConstraintValidator
,则根本不需要任何DI容器。例如,假设您要测试Symfony的
Type
约束,它是TypeValidator
,您可以简单地执行以下操作:通过这个,你可以检查任何约束配置的验证器,你既不需要
ValidatorFactory
,也不需要Symfony内核。更新:正如@ psyloss指出的,这在Symfony 2.5中不起作用,在Symfony〉= 2.1中也不起作用。
ConstraintValidator
的接口被更改了:isValid
被重命名为validate
,并且不再返回布尔值。现在你需要一个ExecutionContextInterface
来初始化一个ConstraintValidator
,而ConstraintValidator
本身至少需要一个GlobalExecutionContextInterface
和一个TranslatorInterface
...所以基本上不需要太多的工作就不可能了。kcugc4gi7#
我看不出WebTestCase有什么问题,如果你不想要客户端,就不要创建;)但是使用一个可能与实际应用程序不同的服务,这是一个潜在的陷阱。因此,我个人是这样做的:
它没有Matt answer那么枯燥--因为您将重复代码(针对每个测试类)并经常 Boot 内核(针对每个测试方法),但它是自包含的,不需要额外的依赖项,因此它取决于您的需要。
而且,当您在希望测试的环境中 Boot 内核时,您肯定拥有应用程序正在使用的相同服务--而不是default或mock。
ifmq2ha28#
如果人们在2023年还在读这篇,更喜欢为Symfony〉3 / 4注入ValidatorInterface。