Skip to content

Commit 2d09d03

Browse files
committed
4.2 Reworked chapter
1 parent a47ef69 commit 2d09d03

File tree

1 file changed

+10
-10
lines changed

1 file changed

+10
-10
lines changed

Part 4 - Concurrency/2. Testing Rx.md

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,19 @@
11
# Testing
22

3-
When designing any system, you also want to test it to guarantee its quality and that this quality does not regress as the system is modified throughout its lifetime. Ideally, you want to automate the process of testing it. Modern software is backed by thorough unit tests and Rx code should be no different.
3+
When designing any system, you want guarantees about the correctness of the operations and that this quality does not regress as the system is modified throughout its lifetime. You'll design tests, which, ideally, should be automated. Modern software is backed by thorough unit tests and Rx code should be no different.
44

55
Testing a synchronous piece of Rx code is as straight-forward as any unit test you are likely to find, using predefined sequences and [inspection](/Part 2 - Sequence Basics/3. Inspection.md). But what about asynchronous code? Consider testing the following piece of code:
66
```java
77
Observable.interval(1, TimeUnit.SECONDS)
88
.take(5)
99
```
10-
That is a sequence that takes 5 seconds to complete. That means every test that uses it will also take 5 seconds or more. That's not convenient at all if you have thousands of tests to run.
10+
That is a sequence that takes 5 seconds to complete. That means every test that uses this sequence will take 5 seconds or more. That's not convenient at all, if you have thousands of tests to run.
1111

1212
## TestScheduler
1313

14-
The piece of code above isn't just time consuming, it actually wastes all that time waiting for time to pass. If you could fast-forward the clock, that sequence would be evaluated almost instantly. Well, you can't fast-forward your system's clock, but Rx sees time through its schedulers. You can have a scheduler that virtualises time, called `TestScheduler`.
14+
The piece of code above isn't just time-consuming, it actually wastes all of that time doing nothing while waiting. If you could fast-forward the clock, that sequence would be evaluated almost instantly. You can't actually fast-forward your system's clock, but you can fast-forward a virtualised clock. It was a design decision in Rx to only use time through schedulers. This decision allows you to replace real time with a scheduler that virtualises time, called `TestScheduler`.
1515

16-
The `TestScheduler` does scheduling in the same way as the schedulers that we saw in the chapter about [Scheduling and threading](/Part 4 - Concurrency/1. Scheduling and threading.md). It schedules actions to be executed either immediately or in the future. The difference is that time is frozen and only progresses upon request.
16+
The `TestScheduler` does scheduling in the same way as the schedulers that we saw in the chapter about [Scheduling and threading](/Part 4 - Concurrency/1. Scheduling and threading.md). It schedules actions to be executed either immediately or in the future. The difference is that time is frozen and only progresses upon request. We decide when time progresses and by how much.
1717

1818
### advanceTimeTo
1919

@@ -56,9 +56,9 @@ Advancing to 40s
5656
Virtual time: 40000
5757
```
5858

59-
We scheduled 3 tasks: one to be executed immediately, and two to be executed in the future. Nothing happens until we advance time, including tasks scheduled immediately. When we advance time, tasks are executed from the queue, until a task that is not ready yet.
59+
We scheduled 3 tasks: one to be executed immediately, and two to be executed in the future. Nothing happens until we advance time, including the tasks scheduled immediately. When we advance time, the scheduler synchronously executes all the tasks that were scheduled for that period of time, in the order of the time they were scheduled for.
6060

61-
You can even set time to a previous moment than the one you are now. That isn't a useful feature as much as a source of bugs in your tests. Usually, `advanceTimeBy` will be closer to what you want to do.
61+
`advanceTimeTo` allows you to set time to any value, including one that is before the current time. This implementation decision can needlessly introduce bugs in the tests, so it is probably better to use the next method, when applicable.
6262

6363
### advanceTimeBy
6464

@@ -151,7 +151,7 @@ Third
151151

152152
## Testing
153153

154-
Rx operators involving asynchronous actions, schedule those actions using a scheduler. If you take a look on all the operators in [Observable](http://reactivex.io/RxJava/javadoc/rx/Observable.html), you will see that such operators have overloads that take a scheduler. This is the way that you can supplement their real-time default schedulers for your `TestScheduler`.
154+
Rx operators which involve asynchronous actions schedule those actions using a scheduler. If you take a look at all the operators in [Observable](http://reactivex.io/RxJava/javadoc/rx/Observable.html), you will see that such operators have overloads that take a scheduler. This is the way that you can supplement their real-time schedulers for your `TestScheduler`.
155155

156156
Here is an example where we will test the output of `Observable.interval` against what we expect it to emit.
157157

@@ -171,12 +171,12 @@ public void test() {
171171
}
172172
```
173173

174-
This is useful for testing small, self-contained pieces of Rx code, such as custom operators. A complete system may be using schedulers on its own, thus defeating our virtual time. [Lee Campbell suggests](http://www.introtorx.com/Content/v1.0.10621.0/16_TestingRx.html#TestingRx) abstracting over Rx's scheduler factories (`Schedulers`), with a provider of our own. When in debug-mode, our custom scheduler factory will replace all schedulers with a `TestScheduler`, which we will then use to control time throughout our system.
174+
This is useful for testing small, self-contained pieces of Rx code, such as custom operators. A complete system may be using schedulers on its own, thus defeating our virtual time. [Lee Campbell suggested](http://www.introtorx.com/Content/v1.0.10621.0/16_TestingRx.html#TestingRx) abstracting over Rx's scheduler factories (`Schedulers`), with a provider of our own. When in debug-mode, our custom scheduler factory will replace all schedulers with a `TestScheduler`, which we will then use to control time throughout our system.
175175

176176

177177
### TestSubscriber
178178

179-
In the test above, we manually collected the values emitted and compared them against what we expected. This process is common enough in tests that Rx comes packaged with `TestScubscriber`, which will do that for us. It collectes every notification received. With `TestSubscriber` our previous test becomes:
179+
In the test above, we manually collected the values emitted and compared them against what we expected. This process is common enough in tests that Rx comes packaged with `TestScubscriber`, which will do that for us. Its event handlers will collect every notification received and make them available for us to inspect. With `TestSubscriber` our previous test becomes:
180180

181181
```java
182182
@Test
@@ -213,7 +213,7 @@ void assertTerminalEvent()
213213
void assertUnsubscribed()
214214
```
215215

216-
There is also a way to block execution until the observable that the `TestSubscriber` is subscribed to terminates.
216+
There is also a way to block execution until the observable, to which the `TestSubscriber` is subscribed, terminates.
217217
```java
218218
void awaitTerminalEvent()
219219
void awaitTerminalEvent(long timeout, java.util.concurrent.TimeUnit unit)

0 commit comments

Comments
 (0)