使用Mockito和InjectMocks

时间:2016-04-05 15:08:44

标签: mockito kotlin

我正在使用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,那么执行惰性块 - 但这不会注入我的模拟。

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

更新:一周缺席后,尝试重复此操作而不做任何更改,我不能。无法解释。

1 个答案:

答案 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中找到完整更新的示例。