@Value lateinit var 仅在从测试调用时才被实例化

Posted

技术标签:

【中文标题】@Value lateinit var 仅在从测试调用时才被实例化【英文标题】:@Value lateinit var is not instantiated only while called from test 【发布时间】:2021-09-12 09:05:39 【问题描述】:

我在测试时无法使用 application.properties 值。

这是我的代码:

@Repository
class RedisSubscriptionStore(): SubscriptionStore 
@Value("\$default.package")
lateinit var defaultPackageForFCMInstance: String 

这按预期工作。它在我的 updateSubscription 方法中使用,具有来自 application.properties 的正确值

问题出在我的测试中,当我使用该类时,该值未实例化并引发错误

@SpringBootTest()
@Tag("integration")
internal class RedisSubscriptionStoreIntegTest @Autowired constructor(
    val objectMapper: ObjectMapper,
    val redisTemplate: RedisTemplate<String, String>
) 
    val sut = RedisSubscriptionStore(redisTemplate, objectMapper)

@Test
    fun `return 200 when updating subscription`() 
        sut.updateSubscription(updatedSub)

        //Assert
        val newlyUpdatedSub = getSubscription(updatedSub.peerID)
        Assertions.assertEquals(updatedSub, newlyUpdatedSub)

但这会引发错误:lateinit 属性 defaultPackageForFCMInstance 尚未初始化

即使这适用于正确的值:

@SpringBootTest()
    @Tag("integration")
    internal class RedisSubscriptionStoreIntegTest @Autowired constructor(
        val objectMapper: ObjectMapper,
        val redisTemplate: RedisTemplate<String, String>
    ) 

     @Value("\$default.package")
     lateinit var defaultPackageForFCMInstance: String

那么为什么从我的测试类调用时我的 defaultPackageForFCMInstance 没有初始化?它显然有一个值,我已经尝试在测试类中打印出来,然后从 sut 调用它

【问题讨论】:

我看不到 sut 是从哪里来的 是RedisSubscriptionStore,我已经更新了 【参考方案1】:

您正在实例化RedisSubscriptionStore

所以 Spring 没有办法注入价值。要么在构造函数中传递值,要么在测试中使用注入

 @Autowired
 var sut: RedisSubscriptionStore

【讨论】:

以上是关于@Value lateinit var 仅在从测试调用时才被实例化的主要内容,如果未能解决你的问题,请参考以下文章

定义全局 android.widget var/val 时的“lateinit”或“by lazy”

Kotlin中,lateinit 和 lazy{} 的区别

我的应用在 iOS 4.3 上崩溃,但仅在从 App Store 下载时

lateinit by lazy

Kotlin 知识点

Kotlin的lateinit