SpringBootTest中@ConfigurationProperties标记的MyProps类加载失败,报Duration类型Bean缺失错误
看起来你遇到的是Spring Boot测试中配置属性类没有被正确识别的问题,我来帮你理清楚原因和解决办法:
问题根源
你在测试类里用@SpringBootTest(classes = [MyProps::class])只指定了MyProps作为要加载的类,这时候Spring容器会把它当成普通的需要依赖注入的Bean,而不是一个从配置文件绑定属性的@ConfigurationProperties类。
因为MyProps是data class,Kotlin会自动生成带所有属性的构造函数,Spring会尝试通过构造函数实例化它,但构造参数是Duration类型——这个类型并没有被注册为Spring容器里的Bean,所以就抛出了"找不到Duration类型Bean"的错误。
解决办法
你需要明确告诉Spring:这个类是用来绑定配置文件属性的,要启用配置属性的绑定机制,下面是几种可行的方案:
方案1:在测试类上添加@EnableConfigurationProperties
直接启用MyProps的配置属性绑定,同时建议加载主应用类(或者至少确保配置机制生效):
@SpringBootTest(classes = [MyApplication::class]) @Tag("integration-test") @EnableConfigurationProperties(MyProps::class) class MyTest { @SpykBean lateinit var myProps: MyProps @Test fun foo() { print(myProps) } }
如果不想加载整个主应用类,也可以只保留@EnableConfigurationProperties,让Spring自动处理配置绑定:
@SpringBootTest @Tag("integration-test") @EnableConfigurationProperties(MyProps::class) class MyTest { @SpykBean lateinit var myProps: MyProps @Test fun foo() { print(myProps) } }
方案2:使用@ConfigurationPropertiesScan扫描配置类
让Spring自动扫描并处理指定包下的@ConfigurationProperties类:
@SpringBootTest @Tag("integration-test") @ConfigurationPropertiesScan(basePackageClasses = [MyProps::class]) class MyTest { @SpykBean lateinit var myProps: MyProps @Test fun foo() { print(myProps) } }
这个注解会告诉Spring去扫描MyProps所在的包,识别出它是配置属性类,自动从application.yaml中读取属性值进行绑定。
方案3:自定义测试配置类
如果需要更精细的控制,可以单独写一个测试用的配置类,专门启用配置属性绑定:
@SpringBootTest @Tag("integration-test") @Import(TestConfig::class) class MyTest { @SpykBean lateinit var myProps: MyProps @Test fun foo() { print(myProps) } } @Configuration @EnableConfigurationProperties(MyProps::class) class TestConfig
关键总结
核心问题是你之前的测试没有启用Spring Boot的配置属性绑定机制,导致Spring把MyProps当成了普通Bean去尝试构造注入。只要通过上面任意一种方式,告诉Spring这个类是用来绑定配置文件的,就能解决这个错误。
内容来源于stack exchange

