Unit testing 用RxJava实现通用可观测的TestScheduler
我开始使用TestScheduler。使用这样的东西,一切都很好:Unit testing 用RxJava实现通用可观测的TestScheduler,unit-testing,rx-java,Unit Testing,Rx Java,我开始使用TestScheduler。使用这样的东西,一切都很好: @Test public void test1() throws Exception { //when TestScheduler scheduler = new TestScheduler(); TestObserver<Long> subscriber = new TestObserver<>(); //run Observable .
@Test
public void test1() throws Exception {
//when
TestScheduler scheduler = new TestScheduler();
TestObserver<Long> subscriber = new TestObserver<>();
//run
Observable
.interval(1L, TimeUnit.SECONDS, scheduler)
.subscribeWith(subscriber);
//check
scheduler.advanceTimeBy(200, TimeUnit.SECONDS);
assertEquals(200, subscriber.valueCount());
}
编辑
如果我使用
@BeforeClass
public static void setupClass() {
mScheduler = new TestScheduler();
RxAndroidPlugins.setInitMainThreadSchedulerHandler(__ -> mScheduler);
RxJavaPlugins.setIoSchedulerHandler(__ -> mScheduler);
}
@Test
public void test2() throws Exception {
//when
TestObserver<Long> subscriber = new TestObserver<>();
//run
Observable
.interval(1L, TimeUnit.SECONDS)
.observeOn(mScheduler)
.subscribeOn(mScheduler)
.subscribeWith(subscriber);
//check
mScheduler.advanceTimeBy(200, TimeUnit.SECONDS);
assertEquals(200, subscriber.valueCount());
}
如果要覆盖标准调度程序,可以将其用于间隔。也可以覆盖其他标准调度程序
RxJavaPlugins.setComputationSchedulerHandler(scheduler -> testScheduler);
testScheduler将是您的testScheduler。设置插件后,可以像test1一样使用advanceTime
示例:
@Test
// fails because interval schedules on different thread then JUnit-Runner-thread -> fall through
void notWorkingTest1() throws Exception {
TestScheduler scheduler = new TestScheduler();
TestObserver<Long> subscriber = new TestObserver<>();
Observable
.interval(1L, TimeUnit.SECONDS)
.observeOn(scheduler)
.subscribeOn(scheduler)
.subscribeWith(subscriber);
//check
scheduler.advanceTimeBy(200, TimeUnit.SECONDS);
assertEquals(200, subscriber.valueCount());
}
@Test
// not working because interval will not be scheduled on virtual time -> JUnit-Runner-Thread will close because test observable emits on different thread
void notWorkingTest2() throws Exception {
//when
TestScheduler scheduler = new TestScheduler();
//run
TestObserver<Long> test = Observable
.interval(1L, TimeUnit.SECONDS)
.observeOn(scheduler)
.subscribeOn(scheduler)
.test();
scheduler.advanceTimeBy(200, TimeUnit.SECONDS);
test.assertValueCount(200);
}
@Test
// runs sync. -> no JUnit-Runner-thread blocking needed
void workingTest() throws Exception {
TestScheduler scheduler = new TestScheduler();
RxJavaPlugins.setComputationSchedulerHandler(s -> scheduler);
TestObserver<Long> test = Observable
.interval(1L, TimeUnit.SECONDS) // executed on Schedulers.computation()
.observeOn(scheduler)
.subscribeOn(scheduler)
.test();
scheduler.advanceTimeBy(200, TimeUnit.SECONDS);
test.assertValueCount(200);
}
如果要覆盖标准调度程序,可以将其用于间隔。也可以覆盖其他标准调度程序
RxJavaPlugins.setComputationSchedulerHandler(scheduler -> testScheduler);
testScheduler将是您的testScheduler。设置插件后,可以像test1一样使用advanceTime
示例:
@Test
// fails because interval schedules on different thread then JUnit-Runner-thread -> fall through
void notWorkingTest1() throws Exception {
TestScheduler scheduler = new TestScheduler();
TestObserver<Long> subscriber = new TestObserver<>();
Observable
.interval(1L, TimeUnit.SECONDS)
.observeOn(scheduler)
.subscribeOn(scheduler)
.subscribeWith(subscriber);
//check
scheduler.advanceTimeBy(200, TimeUnit.SECONDS);
assertEquals(200, subscriber.valueCount());
}
@Test
// not working because interval will not be scheduled on virtual time -> JUnit-Runner-Thread will close because test observable emits on different thread
void notWorkingTest2() throws Exception {
//when
TestScheduler scheduler = new TestScheduler();
//run
TestObserver<Long> test = Observable
.interval(1L, TimeUnit.SECONDS)
.observeOn(scheduler)
.subscribeOn(scheduler)
.test();
scheduler.advanceTimeBy(200, TimeUnit.SECONDS);
test.assertValueCount(200);
}
@Test
// runs sync. -> no JUnit-Runner-thread blocking needed
void workingTest() throws Exception {
TestScheduler scheduler = new TestScheduler();
RxJavaPlugins.setComputationSchedulerHandler(s -> scheduler);
TestObserver<Long> test = Observable
.interval(1L, TimeUnit.SECONDS) // executed on Schedulers.computation()
.observeOn(scheduler)
.subscribeOn(scheduler)
.test();
scheduler.advanceTimeBy(200, TimeUnit.SECONDS);
test.assertValueCount(200);
}
这首先不能工作,因为我没有使用计算调度器。无论如何,即使我重写了其他调度器,结果也与我在test2中得到的结果相同。我编辑了我的问题。请看interval的文档。您将看到,该间隔使用默认的调度程序。默认的调度程序是计算。如果未调用订阅服务器,则可能使用了其他计划程序。因此,您需要阻止JUnit Runner线程,这样该方法就不会失败并中断JVM。我为test2添加了一个示例,该示例正在运行,并提供了一些解释。这首先不能工作,因为我没有使用计算调度器。无论如何,即使我重写了其他调度器,结果也与我在test2中得到的结果相同。我编辑了我的问题。请看interval的文档。您将看到,该间隔使用默认的调度程序。默认的调度程序是计算。如果未调用订阅服务器,则可能使用了其他计划程序。因此,您需要阻止JUnit Runner线程,这样该方法就不会失败并中断JVM。