使用Mockito和InjectMocks时未执行Kotlin延迟块

Jum*_*wah 5 mockito kotlin

我正在使用Mockito来测试我的Kotlin代码.它是一个Web应用程序,我使用spring将值注入某些字段.

例如,我的类片段看起来像这样:

class MyComponent {

    @Inject private lateinit var request: HttpServletRequest
    @Inject private lateinit var database: Database
Run Code Online (Sandbox Code Playgroud)

为了在我的单元测试中模仿这一点,我使用了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)
    }
Run Code Online (Sandbox Code Playgroud)

一切正常.但是,我的组件中也有一个惰性初始化块,如下所示:

val user: User by lazy {
    database.findUser()
}

fun getUsername(): String {
    return user.name
}
Run Code Online (Sandbox Code Playgroud)

当我的测试调用时,myComponent.getUsername()我希望database.findUser()在初始化时调用,user但这不会发生.

如果我在懒惰的区域中放置一个断点,它就永远不会被击中.现在我假设这与Mockito的方式有关,@InjectMocks必须"触摸",user但我真的不知道.如果我MyComponent手动构造然后执行惰性块 - 但这不会注入我的模拟.

如何确保从我的测试中正确调用惰性块?

更新:一个星期缺席后,尝试重现这个没有任何改变,我不能.无法解释.

mie*_*sol 3

我尝试重现您的问题,但未能成功。这个要点提供了一个可行的示例。

不过,我建议重新审视编写测试的方式。考虑以下示例:

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"))
    }
}
Run Code Online (Sandbox Code Playgroud)

在我看来,这比其中提到的要点更容易理解。

如果您感兴趣,mock辅助函数是一个单行函数:

inline fun <reified T : Any> mock() = Mockito.mock(T::class.java)
Run Code Online (Sandbox Code Playgroud)

可以在这个要点中找到完整更新的示例。