基于Kotlin与Spring Boot的JUnit 5:如何正确使用带依赖注入的自定义测试扩展?
解决Spring Boot JUnit 5自定义扩展的依赖注入问题
问题根源
直接通过@ExtendWith(FakeAuthService::class)声明扩展时,JUnit会自行实例化FakeAuthService,这个实例不受Spring容器管理,因此Spring的@Value等依赖注入注解不会被处理,导致url变量未初始化,抛出UninitializedPropertyAccessException。
解决方案:让Spring管理扩展实例
通过@RegisterExtension结合Spring的@Autowired,让Spring创建并管理扩展实例,确保依赖注入生效。
1. 修改测试类
移除@ExtendWith(FakeAuthService::class),改用@Autowired和@RegisterExtension注入扩展:
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, properties = ["spring.cloud.gcp.secretmanager.enabled=false"]) @TestConstructor(autowireMode = TestConstructor.AutowireMode.ALL) class MyTest { @Autowired @RegisterExtension lateinit var fakeAuthService: FakeAuthService // 测试方法... }
2. 保留FakeAuthService的Spring组件配置
确保FakeAuthService被Spring扫描为Bean,保留@Component注解,@Value会被正常处理:
@Component class FakeAuthService : BeforeEachCallback, AfterEachCallback { @Value("\${userendpoint.url}") private lateinit var url: String override fun beforeEach(context: ExtensionContext?) { // 此处url已完成注入,可正常使用 // 执行测试环境搭建逻辑 } override fun afterEach(context: ExtensionContext?) { // 执行测试环境清理逻辑 } }
原理说明
@RegisterExtension告诉JUnit使用这个字段作为测试扩展,而非自行实例化。@Autowired让Spring将容器中管理的FakeAuthService实例注入到测试类字段中,此时实例已完成@Value注入,所有依赖就绪。
内容的提问来源于stack exchange,提问作者Fredrik Folkesson
相关产品推荐
相关产品推荐

