如何使用 mockito 模拟模块范围的扩展方法



这是测试的方法:
它获取一个 URL 并在发送 GET 请求后返回一个 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() }
}

这是测试用例:
我试图模拟即将在这里使用的HttpURLConnection并调用原始方法,然后只需调用该方法并断言模拟是否已设置了预期值。

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 不得为 null at my.spike.pack.http.UtilsKt.getResult(utils.kt:45(

就像模拟不起作用一样。

如何在不更改getJson函数签名的情况下解决此问题?

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

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

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

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

这应该像

    Mockito.`when`(mockConnection.inputStream).thenReturn(ByteArrayInputStream("test".toByteArray()))

相关内容

  • 没有找到相关文章

最新更新