MockWebserver+Retrofit遇SSLHandshakeException连接关闭问题求助
问题解决:MockWebServer SSL握手失败(connection closed)
核心原因
你遇到的SSLHandshakeException: connection closed本质是MockWebServer默认只支持HTTP协议,但拦截器把请求强制改成了HTTPS,而MockWebServer没有配置SSL证书/HTTPS支持,导致服务器无法处理SSL握手,直接关闭连接。
虽然你配置了信任所有证书的OkHttpClient,但这只是客户端的信任策略,服务器端本身没有提供SSL服务,所以握手必然失败。
解决方案(两种可选)
方案一:改用HTTP请求MockWebServer(最简单)
直接修改拦截器里的scheme为HTTP,MockWebServer默认就是HTTP,不需要额外配置:
class DebugUrlInterceptor : Interceptor { override fun intercept(chain: Interceptor.Chain): Response { var request: Request = chain.request() if (MockServerManager.shouldMockApi(request.url.encodedPath)) { val newUrl: HttpUrl = request.url.newBuilder() .scheme(MockServerManager.HTTP_SCHEME) // 替换为HTTP .host(MockServerManager.HOST) .port(MockServerManager.port) .build() request = request.newBuilder() .url(newUrl) .build() // newBuilder()会自动继承原请求的headers、method、body,无需手动重复设置 } return chain.proceed(request) } }
方案二:给MockWebServer配置HTTPS支持
如果必须用HTTPS,需要给MockWebServer配置SSL证书,OkHttp的MockWebServer提供了便捷的配置方法:
// 在测试类初始化MockWebServer时配置HTTPS val mockWebServer = MockWebServer() // 使用OkHttp内置的不安全信任管理器,让MockWebServer支持HTTPS MockWebServer.useHttps(InsecureTrustManager.INSTANCE, false) mockWebServer.start()
同时确保MockServerManager.HTTPS_SCHEME为"https",端口对应MockWebServer启动后的实际端口。
额外检查点
- 验证Dagger注入:确保测试环境下,Retrofit使用的是你配置的
@Named("unsafe")的OkHttpClient,而非生产环境的客户端。 - 调整拦截器顺序:建议把
DebugUrlInterceptor放在HttpLoggingInterceptor之前执行,这样日志能打印修改后的Mock请求URL,方便调试。
内容的提问来源于stack exchange,提问作者Stevie
相关产品推荐
相关产品推荐

