Java 更改JUnit测试顺序会使用来自每个Hibernate验证器的多个JAR文件的验证消息中断测试;s平台资源绑定器

Java 更改JUnit测试顺序会使用来自每个Hibernate验证器的多个JAR文件的验证消息中断测试;s平台资源绑定器,java,bean-validation,hibernate-validator,resourcebundle,spring-validator,Java,Bean Validation,Hibernate Validator,Resourcebundle,Spring Validator,我有一个应用程序运行在Java11上,使用。该应用程序使用多个自定义库jar,每个jar都有自己的ValidationMessages.properties文件,其中包含这些批注的默认消息。使用Hibernate中的内置功能可以将多个JAR文件中的ValidationMessages.properties文件聚合到一个捆绑包中,这是受支持的: @配置 公共类验证配置{ @豆子 公共LocalValidatoryFactoryBean验证器(){ 平台resourceBundleLocator r

我有一个应用程序运行在Java11上,使用。该应用程序使用多个自定义库jar,每个jar都有自己的
ValidationMessages.properties
文件,其中包含这些批注的默认消息。使用Hibernate中的内置功能可以将多个JAR文件中的
ValidationMessages.properties
文件聚合到一个捆绑包中,这是受支持的:

@配置
公共类验证配置{
@豆子
公共LocalValidatoryFactoryBean验证器(){
平台resourceBundleLocator resourceBundleLocator=
新平台ResourceBundleLocator(ResourceBundleMessageInterpolator.USER_VALIDATION_MESSAGES,null,true);
LocalValidatorFactoryBean factoryBean=新的LocalValidatorFactoryBean();
setMessageInterpolator(新的ResourceBundleMessageInterpolator(resourceBundleLocator));
返回factoryBean;
}
}
jar1:ValidationMessages.properties
com.example.CustomValidation1.message=我的自定义消息1
jar2:ValidationMessages.properties
com.example.CustomValidation2.message=我的自定义消息2
项目中有相当数量的单元和集成测试,用于测试验证功能。其中一些测试在Spring聚合消息验证程序bean中自动连接。一些测试(特别是那些在应用程序使用多个
ValidationMessages.properties
)之前的测试)不依赖于返回的确切消息,而是使用默认的Spring验证器,而不使用消息聚合。虽然更新旧的测试可能是有意义的,但为了优先顺序和可用时间,该任务已推迟到将来

运行应用程序时,消息聚合功能正在按预期工作。当我在本地机器上运行测试时,它也按预期工作。但是,当我的项目的测试通过持续集成工具在构建服务器上运行时,一些验证测试失败

我已经根据JUnit测试类的运行顺序确定了失败的发生。测试在本地运行的顺序与在Jenkins上不同(这是允许的,因为Gradle JUnit插件不保证测试类的执行顺序)。具体地说,任何测试是否失败取决于使用消息聚合验证器的测试是否在使用没有消息聚合的验证器的测试之前运行

我已经能够将这个问题归结为一个简单的可在单个测试类中重新创建的失败,如下所示。为了简化示例,编写了
@CustomValidation1
&
@CustomValidation2
验证注释,使验证始终失败

import com.example.CustomValidation1;
导入com.example.CustomValidation2;
导入org.hibernate.validator.MessageInterpolator.ResourceBundleMessageInterpolator;
导入org.hibernate.validator.resourceloading.PlatformResourceBundleLocator;
导入org.junit.FixMethodOrder;
导入org.junit.Test;
导入org.junit.runners.MethodSorters;
导入org.springframework.validation.beanvalidation.localvalidatoryFactoryBean;
导入javax.validation.ConstraintViolation;
导入javax.validation.Validator;
导入java.util.Set;
导入java.util.stream.collector;
导入静态org.junit.Assert.assertEquals;
@FixMethodOrder(MethodSorters.NAME\u升序)
公共类ValidationMessageTests{
私有验证器aggregateMessageValidator=CreateAgregateMessageValidator();
私有验证器standardValidator=createBasicValidator();
专用验证器createBasicValidator(){
LocalValidatorFactoryBean factoryBean=新的LocalValidatorFactoryBean();
factoryBean.AfterPropertieSet();
返回factoryBean;
}
专用验证器CreateAgregateMessageValidator(){
平台resourceBundleLocator resourceBundleLocator=
新平台ResourceBundleLocator(ResourceBundleMessageInterpolator.USER_VALIDATION_MESSAGES,null,true);
LocalValidatorFactoryBean factoryBean=新的LocalValidatorFactoryBean();
setMessageInterpolator(新的ResourceBundleMessageInterpolator(resourceBundleLocator));
factoryBean.AfterPropertieSet();
返回factoryBean;
}
@试验
公共void test1(){
设置冲突=aggregateMessageValidator.validate(new MyInput());
assertEquals(一组(“我的自定义消息1”、“我的自定义消息2”),
冲突.stream().map(ConstraintViolation::getMessage).collect(Collectors.toSet());
}
@试验
公共无效测试2(){
设置冲突=standardValidator.validate(新的MyInput());
assertEquals(2,违例项.size());
}
@自定义验证1
@客户验证2
私有静态类MyInput{
}
}
当在
test2
之前运行
test1
时,两个测试都通过。但是,如果将
test2
重命名为
test0
,使其在
test1
之前运行,
test0
通过,但
test1
失败,出现以下错误:

java.lang.AssertionError:
预期:[我的自定义邮件1,我的自定义邮件2]
实际:[我的自定义消息1,{com.example.CustomValidation2.message}]
为什么更改测试顺序会导致这些测试失败,我该如何修复它


代码当前正在使用带Hibernate Validator 6.0.18的Spring Boot 2.2.4.RELEASE。最终版本。

此问题的根本原因是默认情况下缓存了
ResourceBundle
s。根据:

默认情况下,缓存由
getBundle
工厂方法创建的资源束实例,如果缓存了相同的资源束实例,工厂方法会多次返回该实例

<