There is one last type of predefined scheduler
that we didn't mention in Chapter 6, Using Concurrency and Parallelism with Schedulers. This is the TestScheduler
scheduler, a scheduler
designed to be used in unit tests. All the actions scheduled on it are wrapped in objects containing the time they should be executed at, and won't be executed before the triggerActions()
method of the Scheduler
instance is called. This method executes all of the actions that are not executed and are scheduled to be executed at or before the Scheduler
instance's present time. This time is virtual. This means that it is set by us and we can advance to any moment in the future using the special methods of this scheduler
.
In order to demonstrate it, we'll want to develop another method for creating a new type of observable
. The implementation of the method itself won't be discussed in this chapter, but you can find it in the source code accompanying the book.
The method creates an Observable
instance emitting items at set time intervals. But the intervals are not equally spaced, such as with the built-in interval
method. The idea is that we can provide a list of different multiple intervals and the Observable
instance will cycle through it infinitely. The signature of the method is as follows:
Observable<Long> interval(List<Long> gaps, TimeUnit unit, Scheduler scheduler)
Its behavior should be the same as that of the Observable.interval
method if we pass a List
variable containing only one time period value. And here is the test for this case:
@Test public void testBehavesAsNormalIntervalWithOneGap() { TestScheduler testScheduler = Schedulers.test(); // (1) Observable<Long> interval = CreateObservable.interval( Arrays.asList(100L), TimeUnit.MILLISECONDS, testScheduler ); // (2) TestSubscriber<Long> subscriber = new TestSubscriber<Long>(); interval.subscribe(subscriber); // (3) assertTrue(subscriber.getOnNextEvents().isEmpty()); // (4) testScheduler.advanceTimeBy(101L, TimeUnit.MILLISECONDS); // (5) assertEquals(Arrays.asList(0L), subscriber.getOnNextEvents()); testScheduler.advanceTimeBy(101L, TimeUnit.MILLISECONDS); // (6) assertEquals( Arrays.asList(0L, 1L), subscriber.getOnNextEvents() ); testScheduler.advanceTimeTo(1L, TimeUnit.SECONDS); // (7) assertEquals( Arrays.asList(0L, 1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 9L), subscriber.getOnNextEvents() ); }
Let's take a look at the following explaination:
TestScheduler
instance, using the Schedulers.test()
method.Scheduler
instance as its third parameter. It will emit items on it, so we pass our TestScheduler
instance.TestSubscriber
instance, we subscribe to the Observable
instance.TestScheduler
instance has an advanceTimeBy(long, TimeUnit)
method, which controls the time of its Worker
instances, so we can use it to get 101 milliseconds into the future. After 101 milliseconds, we expect to have received one item—0
.advanceTimeBy()
method, we advance 101 more milliseconds into the future, and we should have received 0
and 1
.TestScheduler
instance is the advanceTimeTo(long, TimeUnit)
method. It can be used to advance to a specific time point in the future. So we use it to get to the moment when exactly one second from the subscription has passed. We expect to have received ten notifications by that time.The TestScheduler
instance controls the time using its advanceTimeBy()
and advanceTimeTo()
methods, so we don't need to block the main Thread
instance waiting for something to happen. We can just go to the time it has already happened. With the TestScheduler
instance, there is a global order of events. So, if two tasks are scheduled for the exact same time, they have an order in which they will execute and can cause problems with the test that expect a specific global order. If we have such an operator to test, we should avoid this by timing to different values—one to 100 ms and the other to 101 ms. Using this technique, testing asynchronous Observable
instances is not such a complex task anymore.
The source code for the preceding test can be found at: https://github.com/meddle0x53/learning-rxjava/blob/master/src/test/java/com/packtpub/reactive/chapter07/CreateObservableIntervalTest.java.
3.15.137.59