使用ReflectionTestUtils.setField设置@Value属性报TypeMismatchException
问题根因
异常发生在Spring ApplicationContext初始化阶段,早于测试代码中ReflectionTestUtils.setField方法的执行时机。Spring容器初始化时会扫描到业务类里的@Value("${temp-files-delete-time}")注解,尝试解析占位符对应的配置值,由于测试环境没有配置temp-files-delete-time对应的属性值,Spring无法解析占位符时会把${temp-files-delete-time}这个原始字符串直接尝试转换为int类型,由此触发NumberFormatException,和后续的反射赋值代码无关。
可行解决方案
- 方案1:测试类添加测试属性配置
在测试类上通过@TestPropertySource注解直接注入需要的属性值,无需修改业务代码,Spring会直接加载该配置完成@Value属性的注入,不需要额外调用ReflectionTestUtils赋值,示例:@SpringBootTest @TestPropertySource(properties = "temp-files-delete-time=1") public class SomeServiceTest { // 测试逻辑 } - 方案2:给@Value注解补充默认值
在业务代码的@Value注解中添加默认值,避免无配置时直接报错,后续可以在测试代码中继续用ReflectionTestUtils.setField覆盖默认值,示例:@Value("${temp-files-delete-time:30}") // 冒号后为默认值,无对应配置时自动生效 private int deleteTime; - 方案3:使用无Spring上下文的纯单元测试
如果测试场景不需要加载完整Spring上下文,可以直接构造业务类实例再调用ReflectionTestUtils赋值,不会触发Spring的@Value解析逻辑,示例:// 无需添加@SpringBootTest等Spring测试注解 public class SomeServiceTest { private SomeService someService = new SomeService(); @BeforeEach public void init() { ReflectionTestUtils.setField(someService, "deleteTime", 1); } // 测试逻辑 }
内容的提问来源于stack exchange,提问作者user3100
相关产品推荐
相关产品推荐

