【问题标题】:How to mock a module wide extension method with mockito?如何使用 mockito 模拟模块范围的扩展方法?
【发布时间】:2018-03-14 01:15:37
【问题描述】:

这是测试方法:
它在发送 GET 请求后获取一个 URL 并返回一个 json。它是一个普通的函数,它位于包中,而不是类中的方法。以下扩展方法的情况相同。

fun getJson (url: String): String {
    val connection = URL(url).openConnection() as HttpURLConnection
    connection.requestMethod = "GET"
    return connection.getResult()
}

这是扩展方法:
它将开始连接并从结果流中读取。

internal fun HttpURLConnection.getResult(charset: Charset = Charsets.UTF_8): String {
    this.connect()
    return this.inputStream.bufferedReader(charset).use { it.readText() }
}

这是测试用例:
我试着mock了这里即将使用的HttpURLConnection并调用原来的方法,然后只调用该方法并断言mock是否已设置为期望值。

class Spike {
    @Test
    fun test_getJson() {
        val expectedResult = "{ok: true}"
        val mockConnection = mock(HttpURLConnection::class.java)
        Mockito.`when`(mockConnection.getResult()).thenReturn(expectedResult)

        getJson("http://www.google.com")

        assertEquals("GET", mockConnection.requestMethod)
        assertEquals("http://www.google.com", mockConnection.url.host)
    }
}

这是错误

java.lang.IllegalStateException: this.inputStream 在 my.spike.pack.http.UtilsKt.getResult(utils.kt:45)​​

就像模拟不工作一样。

如何在不改变getJson函数签名的情况下解决这个问题?

【问题讨论】:

  • 感谢您的来信。现在更清楚了!那行不通:(

标签: unit-testing mocking kotlin mockito


【解决方案1】:

由于 Kotlin 扩展方法在类/字节码级别实现的方式,这将不起作用。

您在源代码中看到的是HttpURLConnection.getResult,但在类/字节码级别还有另一个使用静态方法创建的文件:public final static getResult(HttpURLConnection, Charset)

Mockito 不能模拟静态方法。如果你真的要嘲笑一个,那么我认为PowerMock 有能力做到这一点。

编辑: 如果你有一个模块范围的函数,那么它也会在一个类上生成。假设你有一个文件StreamFunctions.kt 和一个函数:doSomething,那么(默认情况下)将生成一个类StreamFunctionsKt 和一个静态函数doSomething。更多细节可以在这里找到:https://kotlinlang.org/docs/reference/java-to-kotlin-interop.html

【讨论】:

  • 非常感谢,那么模块范围的函数呢,它只是一个位于模块中的函数而不驻留在类中,mockito 可以模拟吗?
【解决方案2】:

这应该像

一样简单
    Mockito.`when`(mockConnection.inputStream).thenReturn(ByteArrayInputStream("test".toByteArray()))

【讨论】:

  • 感谢您的回答,但仍然出现相同的错误。 :(
猜你喜欢
  • 1970-01-01
  • 2011-09-25
  • 2019-01-28
  • 2020-12-08
  • 2010-10-08
  • 1970-01-01
  • 2020-03-20
  • 2011-01-17
相关资源
最近更新 更多