-
Notifications
You must be signed in to change notification settings - Fork 0
TestSubscriber
TestSubscriber is a subscriber that makes it easy to test Observables. Subscribe it to any Observable and the TestSubscriber will record all events the Observable emits and allow you to make assertions against them. Assertions use Hamcrest matchers to make it easy to write readable tests that provide detailed failure messages. While allowing the test to wait for specific events to be emitted so that there are never race conditions in your tests.
@Test
public void someTest() throws Exception{
final TestSubscriber<String> testSubscriber = new TestSubscriber<>();
new ObservableBuilder<String>()
.emit("Glork")
.emit("flork")
.emit("fork")
.emit("spoon")
.sleep(1000)
.error(new Exception("There is no spoon"))
.subscribeOn(Schedulers.io())
.observeOn(Schedulers.computation())
.subscribe(testSubscriber);
testSubscriber.awaitEvent(isErrorThat(hasMessageThat(containsString("no spoon"))));
testSubscriber.assertDoesNotHaveEvent(isError(IOException.class));
testSubscriber.assertHasEvent(isValue("spoon"));
testSubscriber.assertWellBehaved();
testSubscriber.beginAssertionChain()
.assertNextEvent(isValue("Glork"))
.assertNextEvent(isValueThat(containsString("ork")))
.assertNextEvent(isValueThat(endsWith("k")))
.assertNextEvent(isValue("spoon"))
.assertNextEvent(isErrorThat(hasMessageThat(containsString("no spoon"))));
}
Assertion chains allow you to assert that specific events took place in a specific order. Simply call beginAssertionChain() to start the chain and you can make all of your assertions against the chain that is returned. Each assertion will walk through the chain of events received by the TestSubscriber and run your assertions against them. The following calls are available on the assertion chains:
For documentation on what can be done with assertions see the javadoc
The hardest thing about testing complex Observables when working with Schedulers is race conditions. You have to wait for an Observable to emit, which means holding the test thread until the right time. Unfortunately waiting the right amount of time consistently can be difficult. TestSubscriber makes this easy by providing methods that hold the current thread until specific event has occurred. Simply call await event with a matcher for an event, and the test will hold until a matching event has occured, there are even versions that allow you to specify timeouts and how many times the event should be emited before holding the thread.
##Failing The failure messages from all assertions are carefully crafted to provide as much information as possible during a failure. This makes hunting down bugs easy.
All failure messages dump the whole event chain so you can see exactly how the Observable behaved during the test. And assertions that check specific points in the event chain will even points out exactly where a failure occurred.
java.lang.AssertionError:
Expected: onNext with value matching: is "knife"
but: was onNext("spoon")
event chain:
onNext("Glork")
onNext("flork")
onNext("fork")
-------> onNext("spoon")
onError(<java.lang.Exception: There is no spoon>)