首页 > 解决方案 > MockInterceptor 以错误的格式返回内容

问题描述

我为我的测试创建了一个模拟拦截器,经过数小时的调试,结果证明它是一百次崩溃的根源。抛出的异常来自使用 OkHttpClient 的改造:

java.io.IOException: canceled due to java.lang.IllegalStateException: message == null

无法为您提供完整的堆栈跟踪,因为众所周知,运行日志拒绝返回它。然而,不知何故,我仍然设法得到了这条线,这导致了它(因为它被显示了一次),并发现它在我的 MockInterceptor 中,如下所示:

package package.app

import okhttp3.*
import okio.Buffer
import okio.BufferedSource
import java.io.IOException
import java.io.InputStream

class MockInterceptor(private val stream: InputStream) : Interceptor {
    override fun intercept(chain: Interceptor.Chain): Response {
        val body = MockUpBody(stream)
        val content = body.bytes().toString()
        return Response.Builder()
            .protocol(Protocol.HTTP_2)
            // This is essential as it makes response.isSuccessful() returning true.
            .code(200)
            .request(chain.request())
            .body(body)
            .build() -> last mentioned line in stack trace
    }
}
class MockUpBody(private val stream: InputStream) : ResponseBody() {
    override fun contentType(): MediaType? {
        return null
    }

    override fun contentLength(): Long {
        //Means length is unknown beforehand
        return -1
    }

    override fun source(): BufferedSource? {
        return try {
            Buffer().readFrom(stream)
        } catch (exception : IOException) {
            exception.printStackTrace()
            null
        }
    }
}

我正在读取的流来自具有以下内容的文件:

{
  "message" : "Vous ajoutez ces offre avec succes",
  "backend-id": "1234567abc2346789def"
}

进一步的调试告诉我,这是正确读取的,因为 body.byteStream().toString 函数返回

[size=97 text={\r\n  "message" : "Vous ajoutez ces offre avec succes",\r\n  "backe…].inputStream()

这仍然是人类可读的,但由于某种原因,当我要求 bytes().toString() (我猜 HttpClient 也是如此)时,它变得一团糟,返回以下内容:

[B@2e30b66

字节是由 responseBodys 内部函数调用产生的:

source.readByteArray();

所以现在,我们知道,有一个转换错误,我的大问题是:我在哪里解决问题?我是否需要将我的 JSON 文件转换为一堆字节并将其粘贴到文件中?或者我可以以某种方式更改读取流的样式,以便在代码中正确转换?

为了进一步的兴趣,流是这样的:

val stream : InputStream = InstrumentationRegistry
            .getInstrumentation()
            .context.assets.open("new_message.json")

标签: kotlinencodingcharacter-encodingfileinputstream

解决方案


.bytes()函数可能返回一个字节数组(byte[]),对吗?数组的.toString()方法(默认为对象)返回它们的类型和散列(看起来像您收到的输出)。要将字节数组实际转换为 a String,您需要显式转换它:

var string = new String(bytes(), StandardCharsets.UTF_8);

推荐阅读