gpt4 book ai didi

android - 如果发生 HttpException,Retrofit 和 RxJava 的单元测试永远不会完成

转载 作者:行者123 更新时间:2023-11-29 01:22:58 26 4
gpt4 key购买 nike

我正在尝试实现测试 JUnit 的单元测试 ( Retrofit) Observable如果 Web 服务器返回 422 Unprocessable entity .

我有以下 API 服务(我使用 retrofit.create(AccountService.class) 创建):

public interface AccountService {
@POST("users")
Observable<User> createNewUser(@Body User user, @Query("v_uuid") String vUuid, @Query("v_code") String vCode);
}

我从单元测试中调用这个服务:

Observable<User> observable = accountService
.createNewUser(newUser, "uuid", "code")
.subscribeOn(Schedulers.io());

我也用 TestSubscriber<User>为了断言我的 Observable:

TestSubscriber<User> testSubscriber = new TestSubscriber<>(); 

observable
.observeOn(AndroidSchedulers.mainThread())
.subscribe(testSubscriber);

testSubscriber.awaitTerminalEvent();
// assert testSubscriber.getOnErrorEvents()

我使用 SchedulersHook (通过 JUnit @Rule )如以下博文所述:http://alexismas.com/blog/2015/05/20/unit-testing-rxjava/ .我用 Schedulers.immediate()作为以下调度程序的替代:

  • Schedulers.io()
  • Schedulers.computation()
  • Schedulers.newThread()
  • AndroidSchedulers.mainThread()

但似乎测试永远不会完成。当我调用 observable.observeOn(AndroidSchedulers.mainThread()).subscribe(testSubscriber); 时挂起.同时,如果 Web 服务器以 2xx codes 响应,则此代码运行良好。 .另外,如果我删除自定义 SchedulersHook从代码来看,即使服务器以 4xx codes 响应,它也能正常工作.

附加信息:我使用 MockWebServer为了模拟网络服务器,我从日志中看到 Retrofit向服务器发送请求。我的Gradle依赖项如下所示:

testCompile 'junit:junit:4.12'
testCompile 'org.robolectric:robolectric:3.1-SNAPSHOT'
testCompile 'com.squareup.okhttp3:mockwebserver:3.1.2'

compile 'io.reactivex:rxjava:1.1.0'
compile 'io.reactivex:rxandroid:1.1.0'
compile 'com.squareup.okhttp3:okhttp:3.1.2'
compile 'com.squareup.retrofit2:retrofit:2.0.0-beta4'
compile 'com.squareup.retrofit2:adapter-rxjava:2.0.0-beta4'

更新:深入研究后 rxjava我发现使用 merge运算符和不同Schedulers (特别是,用 SchedulersHook 代替它们)导致无限 sleeps()里面的某个地方 OperatorMerge.InnerSubscriber<T> .

最佳答案

我终于弄清楚了代码永远不会完成的原因。感谢来自社区的 Dávid Karnok ( https://groups.google.com/forum/#!topic/rxjava/2rOHj1mvShk ):

What happens is that the RxRingBuffer's cleanup thread sleeps on the immediate scheduler, preventing any progress for other components.

There is a fundamental problem with immediate scheduler; it is not a real scheduler and due to its sleeping nature, it can cause unexpected hangs.

For testing operators, it is much better to use TestScheduler directly and avoid the use of RxJavaPlugins as much as possible.

在我切换到 TestScheduler 之后,一切都按预期开始工作。

还推荐使用依赖注入(inject)(Dagger 2)来管理调度器

关于android - 如果发生 HttpException,Retrofit 和 RxJava 的单元测试永远不会完成,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35683177/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com