我开始使用TestScheduler
。一切都很好用这样的东西:
@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());
}
如果我改用它:
@Test
public void test2() throws Exception {
//when
TestScheduler scheduler = new TestScheduler();
TestObserver<Long> subscriber = new TestObserver<>();
//run
Observable
.interval(1L, TimeUnit.SECONDS)
.observeOn(scheduler)
.subscribeOn(scheduler)
.subscribeWith(subscriber);
//check
scheduler.advanceTimeBy(200, TimeUnit.SECONDS);
assertEquals(200, subscriber.valueCount());
}
测试失败,因为订阅者从未被调用过。
我找到的所有示例都使用带有TestScheduler
的{{1}}并将调度程序传递给工厂方法,就像我在第一个示例中所做的那样。
我不能使用这种方法的原因是,在真实应用程序中,可观察量并不像这一样简单,我无法通过调度程序。
我认为设置Observable.interval
就好像我在第二个例子中这样做会很好,但看起来它不是。
将TestScheduler用于更通用的Observable的正确方法是什么?
不使用TestScheduler我可以成功使用这些方法:
Scheduler
修改
如果我使用
没有区别@Test
public void test3() throws Exception {
//when
Scheduler trampoline = Schedulers.trampoline();
//run
TestObserver<Long> test = Observable
.interval(1L, TimeUnit.SECONDS)
.observeOn(trampoline)
.subscribeOn(trampoline)
.test();
//check
test.await(3100,TimeUnit.MILLISECONDS);
assertEquals(3, test.valueCount());
}
@Test
public void test4() throws Exception {
//when
Scheduler trampoline = Schedulers.trampoline();
//run
TestObserver<Long> test = Observable
.fromArray(1L, 2L, 3L)
.subscribeOn(trampoline)
.observeOn(trampoline)
.test();
//check
assertEquals(3, test.valueCount());
}
@Test
public void test5() throws Exception {
//when
Scheduler trampoline = Schedulers.trampoline();
//run
TestObserver<Long> test = Observable
.fromArray(1L, 2L, 3L)
.subscribeOn(trampoline)
.observeOn(AndroidSchedulers.mainThread())
.test();
//check
test.awaitTerminalEvent();
assertEquals(3, test.valueCount());
}
答案 0 :(得分:2)
如果要覆盖可能使用的标准调度程序(用于间隔)。也可以覆盖其他标准调度程序。
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);
}