使用Square MockWebServer做Android插桩测试遇连接失败问题求助
问题排查与解决方案
核心问题
你的测试代码存在两个关键问题导致连接失败:
- 硬编码固定Base URL:
FakeBaseUrlModule写死了http://localhost:8080/,但 MockWebServer 默认会启动在随机端口,而非固定的8080。 - 初始化顺序错误:先执行
hiltRule.inject()再启动 MockWebServer,导致注入的Base URL是无效的固定值,此时MockWebServer还未启动或使用了其他端口。
修复步骤
1. 移除硬编码,动态获取MockWebServer地址
删除原有的 FakeBaseUrlModule,改为在测试类中通过 @BindValue 提供动态Base URL:
@UninstallModules(UrlModule::class) @HiltAndroidTest @RunWith(AndroidJUnit4::class) class MainActivityTest { @get:Rule val hiltRule = HiltAndroidRule(this) private val mockWebServer = MockWebServer() // 动态绑定MockWebServer的Base URL @BindValue @JvmField val baseUrl: String = mockWebServer.url("/").toString() @Inject lateinit var okHttp: OkHttpClient private lateinit var okHttp3IdlingResource: OkHttp3IdlingResource @Before fun setup() { // 先启动MockWebServer,确保端口已分配 mockWebServer.dispatcher = MockServerDispatcher().RequestDispatcher() mockWebServer.start() // 再执行Hilt注入,此时baseUrl已为正确地址 hiltRule.inject() okHttp3IdlingResource = OkHttp3IdlingResource.create("okhttp", okHttp) IdlingRegistry.getInstance().register(okHttp3IdlingResource) IdlingRegistry.getInstance().register(TestIdlingResource.countingIdlingResource) } // 原有测试方法和teardown逻辑保持不变 }
2. 验证Dispatcher配置
确保 MockServerDispatcher 正确匹配请求路径并返回预期响应(比如包含20条数据的JSON)。若Dispatcher未匹配到请求,也可能触发类似连接异常的错误。
3. 确认测试网络权限
检查测试用的 AndroidManifest.xml 是否包含网络权限:
<uses-permission android:name="android.permission.INTERNET" />
测试环境通常默认开启该权限,但配置异常时也会导致连接失败。
额外提示
- MockWebServer 默认使用随机端口,
mockWebServer.url("/")会返回包含正确主机和端口的完整URL(如http://127.0.0.1:12345/)。 - 若需指定固定端口,可使用
mockWebServer.start(8080),但随机端口能避免测试环境的端口冲突,更推荐使用。
内容的提问来源于stack exchange,提问作者tugceaktepe
相关产品推荐
相关产品推荐

