Как использовать TestScheduler в RxJava
Как использовать RxJava TestScheduler
? Я исхожу из фона .NET, но TestScheduler
в RxJava, похоже, не работает так же, как планировщик тестов в .NET rx.
Вот пример кода, который я хочу проверить
Observable<Long> tick = Observable.interval(1, TimeUnit.SECONDS);
contactsRepository.find(index)
.buffer(MAX_CONTACTS_FETCH)
.zipWith(tick, new Func2<List<ContactDto>, Long, List<ContactDto>>() {
@Override
public List<ContactDto> call(List<ContactDto> contactList, Long aLong) {
return contactList;
}
}).subscribe()
Я пробовал:
subscribeOn(testScheduler)
testScheduler.advanceTimeBy(2, TimeUnit.SECONDS);
testScheduler.triggerActions();
без везения.
Ответы
Ответ 1
Я сделал небольшой пример того, как использовать TestScheduler
. Я думаю, что это очень похоже на реализацию .NET
@Test
public void should_test_the_test_schedulers() {
TestScheduler scheduler = new TestScheduler();
final List<Long> result = new ArrayList<>();
Observable.interval(1, TimeUnit.SECONDS, scheduler).take(5).subscribe(result::add);
assertTrue(result.isEmpty());
scheduler.advanceTimeBy(2, TimeUnit.SECONDS);
assertEquals(2, result.size());
scheduler.advanceTimeBy(10, TimeUnit.SECONDS);
assertEquals(5, result.size());
}
https://github.com/bric3/demo-rxjava-humantalk/blob/master/src/test/java/demo/humantalk/rxjava/SchedulersTest.java
ИЗМЕНИТЬ
Согласно вашему коду: вы должны передать планировщику операцию Observable.interval
, так как это то, что вы хотите контролировать:
TestScheduler scheduler = new TestScheduler();
Observable<Long> tick = Observable.interval(1, TimeUnit.SECONDS, scheduler);
Subscription toBeTested = Observable.from(Arrays.asList(1, 2, 3, 4, 5))
.buffer(3)
.zipWith(tick, (i, t) -> i)
.subscribe(System.out::println);
scheduler.advanceTimeBy(2, TimeUnit.SECONDS);
Ответ 2
у вас есть класс:
public class SomeClass {
public void someMethod() {
Observable<Long> tick = Observable.interval(1, TimeUnit.SECONDS);
contactsRepository.find(index)
.buffer(MAX_CONTACTS_FETCH)
.zipWith(tick, new Func2<List<ContactDto>, Long, List<ContactDto>>() {
@Override
public List<ContactDto> call(List<ContactDto> contactList, Long aLong) {
return contactList;
}
}).subscribe()
}
}
Посмотрите [Observable.interval][1]
в документах, и вы увидите, что он работает с планировщиком вычислений, поэтому давайте переопределим это в нашем тесте.
public class SomeClassTest {
private TestScheduler testScheduler;
@Before
public void before() {
testScheduler = new TestScheduler();
// set calls to Schedulers.computation() to use our test scheduler
RxJavaPlugins.setComputationSchedulerHandler(ignore -> testScheduler);
}
@After
public void after() {
// reset it
RxJavaPlugins.setComputationSchedulerHandler(null);
}
@Test
public void test() {
SomeClass someInstance = new SomeClass();
someInstance.someMethod();
// advance time manually
testScheduler.advanceBy(1, TimeUnit.SECONDS);
}
Это решение является улучшением принятого ответа, поскольку качество, целостность и простота производственного кода поддерживаются.