在测试中更改非主线程调度程序时的最佳做法?

时间:2018-09-08 19:25:43

标签: android rx-java2

关于在测试中使用不同的Schedulers的讨论很多,并且有很多解决方案来实现这一目标:

我了解为什么我应该用另一个调度程序替换AndroidSchedulers.mainThread(),所以看不到this problem

但是我不完全理解用.io()替换computation()trampoline()调度程序的原因吗?

大概这将同步所有Rx流。假设我有两个流:一个在构造函数中,一个在someMethod ***中:

import android.util.Log;
import io.reactivex.Observable;
import io.reactivex.schedulers.Schedulers;

public class MyClass {
    private Integer currentNumber;

    public MyClass() {
        Observable.just(1, 2, 3)
                .subscribeOn(Schedulers.io())
                .subscribe(integer -> currentNumber = integer);
    }

    public void someMethod() {
        Observable.just("A", "B", "C")
                .subscribeOn(Schedulers.io())
                .subscribe(s -> {
                    // add current string to current number
                    Log.d("TAG", s + currentNumber);
                });
    }
}

实际上,我永远不会在currentNumber上获得NPE,因为可观察到的构造函数会在调用someMethod之前很久就完成。但是在测试中:

@Test
public void someMethodTest() {
    MyClass myClass = new MyClass();
    myClass.someMethod();
}

我将在currentNumber上获得NPE。从技术上讲,这是一个竞赛条件,但我只能在测试中看到它。过去,我已通过以下方式解决此问题:

@Test
public void someMethodTest() throws Exception {
    MyClass myClass = new MyClass();
    Thread.sleep(100); // sleep to allow constructor's observable to complete.
    myClass.someMethod();
}

那么在测试中替换非主线程调度程序是一个好主意吗?理想情况下,我希望测试尽可能与真实代码相似。我是否应该通过重构MyClass来解决竞争条件?

*** 这是一个简单的示例,但是当我在构造函数中订阅BehaviorSubjectReplaySubject时,我看到了很多,我希望观察到几乎立即值。

0 个答案:

没有答案