我正在使用Mockito来测试我的Kotlin代码。它是一个Web应用程序,我使用spring将值注入某些字段。
例如,我的类片段看起来像这样:
class MyComponent {
@Inject private lateinit var request: HttpServletRequest
@Inject private lateinit var database: Database
要在我的单元测试中模仿这一点,我使用Mockito的@Mock
和@InjectMocks
注释。所以我的测试看起来像这样:
class MyComponentTest {
@Mock private lateinit var request: HttpServletRequest
@Mock private lateinit var database: Database
@InjectMocks private lateinit var sut: MyComponent
@Before
fun setup() {
MockitoAnnotations.initMocks(this)
}
一切正常。但是,我的组件中也有一个惰性初始化块,如下所示:
val user: User by lazy {
database.findUser()
}
fun getUsername(): String {
return user.name
}
当我的测试调用myComponent.getUsername()
时,我希望在初始化database.findUser()
时调用user
,但这不会发生。
如果我在懒人区块中放置一个断点,它就永远不会被击中。现在我假设这与Mockito和@InjectMocks
必须“触摸”user
的方式有关,但我真的不知道。如果我手动构造MyComponent
,那么执行惰性块 - 但这不会注入我的模拟。
如何确保从我的测试中正确调用惰性块?
更新:一周缺席后,尝试重复此操作而不做任何更改,我不能。无法解释。
答案 0 :(得分:3)
我试图重现您的问题而无法这样做。这个gist提供了一个工作示例。
但是我建议您重新考虑编写测试的方式。请考虑以下示例:
class MyComponentTest {
val request = mock<HttpServletRequest>()
val database = mock<Database>()
val sut = MyComponent(request, database)
@Test
fun username() {
Mockito.`when`(database.findUser()).thenReturn(User("test"))
val username = sut.getUsername()
MatcherAssert.assertThat(username, Matchers.equalTo("test"))
}
}
在我看来,比上面提到的the gist更容易理解。
如果你对[{1}}帮助函数感兴趣,那就是一个单行程序:
mock
可在此gist中找到完整更新的示例。