gpt4 book ai didi

java - RxJava : puzzling behavior

转载 作者:行者123 更新时间:2023-12-02 10:38:58 25 4
gpt4 key购买 nike

我希望类中的方法在 IO 线程上运行一些代码,但只有当它们订阅的主题具有特定值时。然后调用者应该在 Android UI 线程上收到响应。

类似这样的事情:

public class MyClass {

private final Subject<Boolean, Boolean> subject;
private final OtherClass otherObject;

public MyClass(Subject<Boolean, Boolean> subject,
OtherClass otherObject) {
this.subject = subject;
this.otherObject = otherObject;
}

public Observable<String> myMethod() {
return waitForTrue(() -> otherObject.readFromDisk());
}

private <T> Observable<T> waitForTrue(Callable<T> callable) {
return subject
.first(value -> value)
.flatMap(value -> Observable.fromCallable(callable))
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread());
}
}

这个有用吗?不确定,所以我编写了一组单元测试来检查它们。我发现我的测试方法虽然在逐个运行时总是有效,但作为套件的一部分却会失败。

事实上,我发现如果我进行两次相同的测试,第一次会通过,但第二次会失败!

public class MyClassTest {

private TestScheduler ioScheduler;
private TestScheduler androidScheduler;
private TestSubscriber<String> testSubscriber;
private MyClass objectUnderTest;

@Before public void setup() {
ioScheduler = new TestScheduler();
androidScheduler = new TestScheduler();
testSubscriber = new TestSubscriber<>();
RxJavaHooks.reset();
RxJavaHooks.setOnIOScheduler(scheduler -> ioScheduler);
RxAndroidPlugins.getInstance().reset();
RxAndroidPlugins.getInstance().registerSchedulersHook(
new RxAndroidSchedulersHook() {
@Override public Scheduler getMainThreadScheduler() {
return androidScheduler;
};
});
Subject<Boolean, Boolean> subject = BehaviorSubject.create(true);
MyClass.OtherClass otherClass = mock(MyClass.OtherClass.class);
when(otherClass.readFromDisk()).thenReturn("mike");;
objectUnderTest = new MyClass(subject, otherClass);
};

@Test public void firstTest() {
objectUnderTest.myMethod().subscribe(testSubscriber);
ioScheduler.advanceTimeBy(1, TimeUnit.SECONDS);
androidScheduler.advanceTimeBy(1, TimeUnit.SECONDS);
testSubscriber.assertValueCount(1);
// This passes
};

@Test public void secondTest() {
firstTest();
// This fails!
};
}

为什么会发生这种情况?错误是在被测类中,还是在测试代码中?

我认为这可能是使用 RxJava 1.x 的问题,但我在使用 RxJava 2.x 时也遇到了类似的问题。

编辑:由于测试代码中缺少行,测试失败。您必须将其放入设置方法中:

AndroidSchedulers.reset()

因为该钩子(Hook)仅由 AndroidSchedulers 类的静态初始化程序调用一次。

最佳答案

subscribeOnSubject 没有实际效果,因为它们没有订阅副作用以转移到另一个线程。因此,当他们获得新项目时,他们会在调用者线程上通知消费者。将项目移动到另一个线程应该通过observeOn来完成:

private <T> Observable<T> waitForTrue(Callable<T> callable) {
return subject
.filter(value -> value)
.take(1)
.observeOn(Schedulers.io())
.map(value -> callable.call())
.observeOn(AndroidSchedulers.mainThread());
}

此外,您不需要 flatMap 来执行 callable,map 就足够了。

关于java - RxJava : puzzling behavior,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53065929/

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