Reputation: 3769
This is the method to test:
It gets an URL and return a json after sending a GET request. It is a plain function which sits in a package rather than a method from a class. Same case for the extension method below.
fun getJson (url: String): String {
val connection = URL(url).openConnection() as HttpURLConnection
connection.requestMethod = "GET"
return connection.getResult()
}
This is the extension method:
It will start connecting and read from result stream.
internal fun HttpURLConnection.getResult(charset: Charset = Charsets.UTF_8): String {
this.connect()
return this.inputStream.bufferedReader(charset).use { it.readText() }
}
This is the test case:
I tried to mock the HttpURLConnection
that is about to be used here and call the original method, then just call the method and assert whether the mock has been set with the expected value.
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)
}
}
This is the error
java.lang.IllegalStateException: this.inputStream must not be null at my.spike.pack.http.UtilsKt.getResult(utils.kt:45)
It just like the mock is not working.
How to solve this without changing the signature of the getJson
function?
Upvotes: 0
Views: 1390
Reputation: 4432
This will not work because of the way Kotlin extension methods are implemented on the class / bytecode level.
What you see in source code is HttpURLConnection.getResult
but on the class/bytecode level there is another file created with a static method: public final static getResult(HttpURLConnection, Charset)
.
Mockito cannot mock static methods. If you really have to mock one, then I think PowerMock is capable of doing that.
Edit:
If you have a module wide function then it is also generated on a class. Assuming you have a file StreamFunctions.kt
with a function: doSomething
then, there will be (by default) generated class StreamFunctionsKt
with a static function doSomething
. More details can be found here: https://kotlinlang.org/docs/reference/java-to-kotlin-interop.html
Upvotes: 1
Reputation: 2931
That should be as easy as
Mockito.`when`(mockConnection.inputStream).thenReturn(ByteArrayInputStream("test".toByteArray()))
Upvotes: 0