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
相关产品推荐
相关产品推荐

