【发布时间】:2022-01-19 21:51:42
【问题描述】:
我在我的 android 项目中使用 KTor 和 Kotlin 序列化 库,以及 mockk 和 junit.jupiter用于单元测试。我在模拟 ktor 的 suspend 函数 readText() 时遇到了一些问题。编写的单元测试测试initErrorMessage()函数返回正确的错误信息。
测试类:
class ErrorTest {
private val errorMessage = "objectId must be provided."
private val errorCode = 2689
private val correctResponseJson = "{\"code\":$errorCode,\"message\":\"$errorMessage\"}"
// ResponseException class is from ktor library
private val exceptionMock: ResponseException = mockk(relaxed = true)
@Test
fun `initErrorMessage should return correct error message`() = runTest {
coEvery { exceptionMock.response.readText() } returns correctResponseJson // <-- here is the Error occurs
val expectedError = errorMessage
val actualError = initErrorMessage(exceptionMock)
assertEquals(expectedError, actualError)
}
}
测试方法:
suspend fun initErrorMessage(cause: ResponseException): String {
return try {
val body = cause.response.readText()
val jsonSerializer = JsonObject.serializer()
val jsonObj = Json.decodeFromString(jsonSerializer, body)
jsonObj["message"].toString()
} catch (e: Exception) {
""
}
}
在测试方法的第一行执行期间,我得到一个错误:
Premature end of stream: expected 1 bytes
java.io.EOFException: Premature end of stream: expected 1 bytes
at io.ktor.utils.io.core.StringsKt.prematureEndOfStream(Strings.kt:492)
at io.ktor.utils.io.core.internal.UnsafeKt.prepareReadHeadFallback(Unsafe.kt:78)
at io.ktor.utils.io.core.internal.UnsafeKt.prepareReadFirstHead(Unsafe.kt:61)
at io.ktor.utils.io.charsets.CharsetJVMKt.decode(CharsetJVM.kt:556)
at io.ktor.utils.io.charsets.EncodingKt.decode(Encoding.kt:103)
at io.ktor.utils.io.charsets.EncodingKt.decode$default(Encoding.kt:101)
at io.ktor.client.statement.HttpStatementKt.readText(HttpStatement.kt:173)
at io.ktor.client.statement.HttpStatementKt.readText$default(HttpStatement.kt:168)
at com.example.android.http.error.ErrorTest$initErrorMessage should return correct error message$1$1.invokeSuspend(ErrorTest.kt:37)
at com.example.android.http.error.ErrorTest$initErrorMessage should return correct error message$1$1.invoke(ErrorTest.kt)
at com.example.android.http.error.ErrorTest$initErrorMessage should return correct error message$1$1.invoke(ErrorTest.kt)
at io.mockk.impl.eval.RecordedBlockEvaluator$record$block$2$1.invokeSuspend(RecordedBlockEvaluator.kt:28)
at io.mockk.impl.eval.RecordedBlockEvaluator$record$block$2$1.invoke(RecordedBlockEvaluator.kt)
at io.mockk.InternalPlatformDsl$runCoroutine$1.invokeSuspend(InternalPlatformDsl.kt:20)
如何模拟这个suspend 方法readText() 而不出现错误?
【问题讨论】:
标签: android unit-testing kotlin kotlin-coroutines ktor