java - 将 Java Mockito 测试转换为 Kotlin

标签 java kotlin mockito

我在将以下工作 Java 测试转换为 Kotlin

时遇到问题
@Test
public void testSomething() {

    Mockito.when(parkIdMappingRepository.save(Mockito.any(ParkIdMapping.class))).thenAnswer(
        (Answer<ParkIdMapping>) invocation -> {
            ParkIdMapping mapping = invocation.getArgument(0);
            mapping.setId(100L);
            return mapping;
        }
    );
    ParkIdMapping mapping = parkIdMappingRepository.save(new ParkIdMapping("123"));

    assertEquals(new Long(100L), mapping.getId());

Intellij Idea 到 Kotlin 的转换结果:

@Test
public fun test_correctParkIdMappingGeneration() {

    Mockito.`when`(parkIdMappingRepository.save(Mockito.any(ParkIdMapping::class.java))).thenAnswer(
        { invocation -> // compiler error
            val mapping = invocation.getArgument(0)
            mapping.id = 100L
            mapping
        } as Answer<ParkIdMapping>
    )
    val mapping = parkIdMappingRepository.save(ParkIdMapping("123"))

    assertEquals(100L, mapping.id)
}

然而,带有 lambda 参数 'invocation' 的行会导致编译器错误:

Cannot infer a type for this parameter. Please specify it explicitly .

我试过像这样调整 lambda

    Mockito.`when`(parkIdMappingRepository.save(Mockito.any(ParkIdMapping::class.java))).thenAnswer(
        { invocation: InvocationOnMock ->
            val mapping = invocation.getArgument(0) as ParkIdMapping
            mapping.id = 100L
            mapping
        } as Answer<ParkIdMapping>
    )

导致

java.lang.ClassCastException: com.foobar.ParkIdGenerationServiceTest$test_correctParkIdMappingGeneration$1 cannot be cast to org.mockito.stubbing.Answer

org.mockito.exceptions.misusing.UnfinishedStubbingException: Unfinished stubbing detected here: -> at com.foobar.ParkIdGenerationServiceTest.testSomething(ParkIdGenerationServiceTest.kt:92)

初衷是修改传递给repositorysave方法的实体并返回。有什么想法该怎么做?

最佳答案

将未检查的转换移动到 Answer<ParkIdMapping>getArgument称呼。

此外,您还需要添加 helper mock 方法。 Mockito.any()由于 Kotlin 的 Null 安全特性,在它的验证函数中返回 null 并且模拟抛出 NPE。

像这样:

fun <T> any(): T {
    Mockito.any<T>()
    return uninitialized()
}

fun <T> uninitialized(): T = null as T

测试将是:

@Test
public fun test_correctParkIdMappingGeneration() {

    Mockito.`when`<ParkIdMapping>(parkIdMappingRepository.save(any())).thenAnswer(
        { invocation -> // compiler error
            val mapping = invocation.getArgument<ParkIdMapping>(0)
            mapping.id = 100L
            mapping
        }
    )
    val mapping = parkIdMappingRepository.save(ParkIdMapping("123"))

    assertEquals(100L, mapping.id)
}

关于 Kotlin 和 Mockito 互操作的 future 阅读:https://medium.com/@elye.project/befriending-kotlin-and-mockito-1c2e7b0ef791

关于java - 将 Java Mockito 测试转换为 Kotlin,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52421802/

相关文章:

java - 如何在 Mockito 中多次 stub 异常

android - 在android中获取mp3持续时间

java - 安卓 : transfer a view from a parent to another one

kotlin - 从 Kotlin 中的密封类扩展数据类

java - 尝试找到使用mockito调用匿名内部回调的最佳实践

java - stub 检查异常 : how to handle the exception

java - 在爬行超过一个页面时遇到逻辑问题,仅适用于第一页和第二页

java - playOrm - 初始测试文件运行 - TestManyToOne.java

java - AlarmManager 服务始终每分钟运行一次

android - Android SlowGradleBuild