【问题标题】:Convert Java Mockito test to Kotlin将 Java Mockito 测试转换为 Kotlin
【发布时间】:2018-09-20 09:28:08
【问题描述】:

我在将以下工作 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”的行会导致编译器错误:

无法推断此参数的类型。请明确说明。

我试着像这样调整 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 无法转换为 org.mockito.stubbing.Answer

org.mockito.exceptions.misusing.UnfinishedStubbingException: 此处检测到未完成的存根: -> 在 com.foobar.ParkIdGenerationServiceTest.testSomething(ParkIdGenerationServiceTest.kt:92)

本意是修改传递给repositorysave方法的实体并返回。任何想法该怎么做?

【问题讨论】:

    标签: java kotlin mockito


    【解决方案1】:

    将未经检查的演员转换为 Answer&lt;ParkIdMapping&gt;getArgument 调用。

    另外,您需要添加辅助模拟方法。 Mockito.any() 在其验证函数中返回 null,并且由于 Kotlin 的 Null 安全特性,mock 会抛出 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 互操作的未来阅读:https://medium.com/@elye.project/befriending-kotlin-and-mockito-1c2e7b0ef791

    【讨论】:

    • 感谢您的快速回复。现在我在when(测试正文中的第一行)出现编译器错误,“类型推断失败。没有足够的信息来推断 *fun when (methodCall: T!) 中的参数 T: OngoingStubbing!请明确说明“我错过了什么吗?
    • 尝试明确指定when的参数:Mockito.`when`&lt;ParkIdMapping&gt;()
    • 像魅力一样工作。我随时更新您的 sn-p 并将您的答案标记为已解决。非常感谢。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-11-26
    • 1970-01-01
    • 2019-09-11
    • 2018-07-01
    • 2021-08-16
    • 2021-02-03
    • 2019-03-12
    相关资源
    最近更新 更多