在 Kotlin 中使用 Mockito 的 doAnswer

21

这段Java代码在Kotlin中的等效代码会是什么?

doAnswer(new Answer() {
    @Override
    public Object answer(InvocationOnMock invocation) throws Throwable {
        Design design = new Design();
        GetDesign.Listener callback = (GetDesign.Listener) invocation.getArguments()[0];
        callback.onSuccess(design);
        return null;
    }
}).when(someRepository).getDesign(any(GetDesign.Listener.class));

[更新] 经过尝试多种选项,最终我使用mockito-kotlin使其工作。 我认为这是实现doAnswer最舒适的方式。 语法几乎保持不变:

doAnswer {
    callback = it.arguments[0] as GetDesign.Listener
    callback.onSuccess(Design())
    null
}.whenever(someRepository).execute(any(GetDesign.Listener::class.java))

完整的代码和build.gradle配置可以在此处找到。


注意:我建议研究一下这些Kotlin Mockito绑定:https://github.com/nhaarman/mockito-kotlin。它们为您提供了很多很酷的东西(例如,使用`whenever`代替`\`when\`)。 - Oliver Charlesworth
我看了一下,但它能在Kotlin 1.1.1上运行吗? - voghDev
我猜你需要进行SAM转换。请参考这里:https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions - marstran
只在我的电脑上运行 :) - Oliver Charlesworth
使用mockito-kotlin也使其工作了。正在尝试以“原始方式”使其工作,一旦得出结论,将更新答案。 - voghDev
3个回答

32
doAnswer {
    val design = Design()

    val callback = it.arguments[0] as GetDesign.Listener
    callback.onSuccess(design)

    null // or you can type return@doAnswer null

}.`when`(someRepository).getDesign(any(GetDesign.Listener::class.java))

2
如果这个答案解决了你的问题,请考虑通过点击勾选标记接受它。这将向更广泛的社区表明你已经找到了解决方案,并为回答者和你自己赢得一些声誉。这并非义务性的。 - Sufian
2
这确实是正确的答案。我只会用“whenever”替换“when”,因为mockito-kotlin添加了这个函数,看起来更加简洁。我也会更新问题文本。谢谢。 - voghDev

0

现在你也可以像这样做(假设类型是Repository):

    mock<Repository>() {
        on { getDesign(any() as GetDesign.Listener) } doAnswer {
            val callback = it.arguments[0] as GetDesign.Listener
            callback.onSuccess(Design())
            null
        }
    }

0

我是Full Mocking object的粉丝,我不想加载任何配置或其他Spring Boot依赖注入。

如果我必须Mock一个JavaMailSender函数,我会像这样做。我将使用theAnswer来返回值。

Kotlin(只测试JavaMailSender)

@Test
fun javaMailSenderTest(){
val jms = mock(JavaMailSender::class.java)
val mimeMessage = mock(MimeMessage::class.java)
mimeMessage.setFrom("no-reply@example.com")
mimeMessage.setText("Just a body text")

Mockito.`when`(jms.send(mimeMessage)).thenAnswer {
  // val callback = it.arguments[0]  <- Use these expression to get params values
  // Since JavaMailSender::send() function retrun void therefore, we should return Unit
  Unit
}

assertEquals(jms.send(mimeMessage), Unit)

}

Kotlin(使用自定义类发送JavaMailSender)

有可能您正在使用自己的自定义类来发送邮件,所以我在这里已经完成了它。

@Test
fun updateMembers&SendEmailTest() {

val mockEmailService= mock(MyEmailServiceImplementor::class.java)

// sendInfoMail(true|false) is my custom implemention of JavaMailSender
Mockito.`when`(mockEmailService.sendInfoMail(true)).thenAnswer { invocation ->
  Unit
}

assertEquals(mockEmailService.sendInfoMail(true), Unit)

}

希望这可以帮助到某些人。如果你需要Java版本,请在评论中告诉我。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接