You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android单元测试中Retrofit+RxJava请求无法终止问题求助

解决Retrofit2+RxJava2真实HTTP请求单元测试无法终止的问题

嘿,我看了你的测试代码,请求一直卡着不终止的问题,主要有几个关键点需要调整,咱们一步步来:

1. 确保Retrofit的RxJava CallAdapter正确配置

你的RxImmediateSchedulerRule把所有Rx调度器换成了trampoline(),但如果Retrofit没有用RxJava的CallAdapter,或者没指定调度器,那真实请求会跑在OkHttp自己的线程池里,完全不受Rx规则的控制,自然会卡住awaitTerminalEvent()。

检查你的Retrofit构建代码,必须添加RxJava2的CallAdapter,并且明确指定IO调度器:

val retrofit = Retrofit.Builder()
    .baseUrl("你的API地址")
    .addConverterFactory(GsonConverterFactory.create())
    // 关键:用createWithScheduler指定IoScheduler,这样请求线程才会被Rx规则接管
    .addCallAdapterFactory(RxJava2CallAdapterFactory.createWithScheduler(Schedulers.io()))
    .client(OkHttpClient.Builder().build())
    .build()

2. 配置Robolectric允许真实网络请求

默认情况下Robolectric会拦截所有网络请求,模拟返回。如果你要发真实请求,必须在测试类的@Config里开启网络支持:

@Config(sdk = [Build.VERSION_CODES.O_MR1], networkConfig = NetworkConfig.LOCAL)

这个配置会让Robolectric放行真实的网络请求,而不是拦截模拟。

3. 给awaitTerminalEvent添加超时时间

就算前面都配置对了,网络请求也可能因为环境问题卡住,给awaitTerminalEvent()加个超时,避免测试无限挂起:

loginRequestTestObserver.apply {
    awaitTerminalEvent(5, TimeUnit.SECONDS) // 5秒超时,方便调试
    assertNoErrors()
    assertComplete()
    assertValueCount(1)
}

4. 移除重复的Mockito初始化

你的测试类里同时用了@Rule MockitoJUnit.rule()和@Before里的MockitoAnnotations.initMocks(this),这两个是重复的,会导致Mock对象被初始化两次,可能引发奇怪的问题,把@Before里的代码删掉就行。

额外注意点

  • 测试真实请求时,确保你的测试环境(比如本地机器、CI服务器)能正常访问目标API,没有代理、防火墙或者证书问题
  • 真实请求的单元测试其实不太推荐,因为依赖外部环境,容易不稳定。如果只是验证字段逻辑,建议用MockWebServer来模拟API响应,这样测试更可靠

修改完这些之后,再跑测试应该就能正常终止了。

内容的提问来源于stack exchange,提问作者SirVX123

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.06 14:57:33