SlideShare uma empresa Scribd logo
1 de 25
Baixar para ler offline
RXJAVA2
TIPS AND TRICKS
@STEPANGO
ABOUT ME
▸ Android developer since 2008
▸ Lead Android Engineer @ 90Seconds.tv
▸ Kotlin and Rx addict
▸ RxKotlin contributor
▸ RxDataBindings author
Event Iterable Observable
retrieve data T next() onNext(T)
discover error throw Exception onError(Exception)
complete !hasNext() onCompleted()
transform fromIterbale() toList()
SHORTEST RX INTRO EVER
1.0 VS 2.0
▸ Mar 2018 - end of rxJava1 support
▸ Better performance
▸ Lower memory consumption
▸ Can’t use null
▸ Reactive-Streams based
▸ Maybe, Flowable
OBSERVABLE AND FRIENDS
▸ Flowable: 0..N flows, supporting Reactive-Streams and
backpressure
▸ Observable: 0..N flows, no backpressure
▸ Single: a flow of exactly 1 item or an error
▸ Completable: a flow without items but only a completion
or error signal
▸ Maybe: a flow with no items, exactly one item or an error
HOW TO DEAL WITH NULLS
▸ Null object pattern
▸ Optional
▸ State wrappers
NULL OBJECT PATTERN
interface Animal {
void makeSound();
}
class Dog implements Animal {
public void makeSound() {
System.out.println("woof!");
}
}
enum NullAnimal implements Animal {
INSTANCE;
public void makeSound() {};
}
void execute() {
List<Animal> animals = Arrays.asList(NullAnimal.INSTANCE, new Dog());
Observable.fromIterable(animals)
.filter(animal J> animal != NullAnimal.INSTANCE)
.subscribe(AnimalKLmakeSound);
}
STREAM OF OPTIONAL VALUES
interface Animal {
void makeSound();
}
class Dog implements Animal {
public void makeSound() {
System.out.println("woof!");
}
}
public void execute() {
List<Optional<Animal>> animals = Arrays.asList(
Optional.<Animal>empty(), Optional.of(new Dog())
);
Observable.fromIterable(animals)
.filter(OptionalKLisPresent)
.map(OptionalKLget)
.subscribe(AnimalKLmakeSound);
}
STREAM OF STATES
class AnimalStateSuccess implements AnimalState {
Animal animal;
AnimalStateSuccess(Animal animal) { this.animal = animal; }
@Override public boolean hasAnimal() { return true;}
@Override public Animal animal() { return animal; }
@Override public String errorMsg() { return null; }
}
enum AnimalStateError implements AnimalState {
INSTANCE;
@Override public boolean hasAnimal() { return false;}
@Override public Animal animal() { return null; }
@Override public String errorMsg() { return "We lost him"; }
}
public void execute() {
List<AnimalState> animals = Arrays.asList(
AnimalStateError.INSTANCE, new AnimalStateSuccess(new Dog())
);
Observable.fromIterable(animals)
.filter(AnimalStateKLhasAnimal)
.map(AnimalStateKLanimal)
.subscribe(AnimalKLmakeSound);
}
TESTING IS EASY
▸ Blocking calls
▸ TestSubscriber TestObserver
▸ RxJavaPlugins
▸ await()/awaitTerminalEvent()
▸ TestScheduler
BLOCKING CALLS
Observable<Integer> observable = Observable.just(1, 2);
int first = observable.blockingFirst();
assertEquals(first, 1);
int last = observable.blockingLast();
assertEquals(last, 2);
Iterable<Integer> integers = observable.blockingIterable();
int sum = 0;
for (Integer integer : integers) sum += integer;
assertEquals(sum, 3);
TEST SUBSCRIBER
Observable.just(1, 2)
.test()
.assertNoErrors()
.assertComplete()
.assertResult(1, 2)
.assertNever(3);
TEST SUBSCRIBER
Observable.timer(1, TimeUnit.SECONDS)
.flatMap(ignore J> Observable.just(1, 2))
.test()
.assertNoErrors()
.assertComplete()
.assertResult(1, 2)
.assertNever(3);
TEST SUBSCRIBER
Observable.timer(1, TimeUnit.SECONDS)
.flatMap(ignore J> Observable.just(1, 2))
.test()
.assertNoErrors()
.assertComplete()
.assertResult(1, 2)
.assertNever(3);
FAIL
TEST SUBSCRIBER
Observable.timer(1, TimeUnit.SECONDS)
.flatMap(ignore J> Observable.just(1, 2))
.test()
.await()
.assertNoErrors()
.assertComplete()
.assertResult(1, 2)
.assertNever(3);
AWAIT TERMINAL EVENT
boolean hasTerminalEvent = Observable.timer(1, TimeUnit.SECONDS)
.flatMap(ignore J> Observable.just(1, 2))
.test()
.awaitTerminalEvent(500, TimeUnit.MILLISECONDS);
assertFalse(hasTerminalEvent);
PREVENT FROM FAILING
Observable.timer(1, TimeUnit.SECONDS)
.flatMap(ignore J> Observable.just(1, 2))
.test()
.assertNoErrors()
.assertComplete()
.assertResult(1, 2)
.assertNever(3);
UNIT TEST RULE
@Rule
final TrampolineSchedulersRule schedulers = new
TrampolineSchedulersRule();
@Test
public void observerTest() throws InterruptedException {
Observable.timer(1, TimeUnit.SECONDS)
.flatMap(ignore J> Observable.just(1, 2))
.test()
.assertNoErrors()
.assertComplete()
.assertResult(1, 2)
.assertNever(3);
}
TEST SUBSCRIBER
public class TrampolineSchedulersRule implements TestRule {
@Override
public Statement apply(final Statement base, Description description) {
return new Statement() {
@Override public void evaluate() throws Throwable {
RxJavaPlugins.setIoSchedulerHandler(
scheduler J> Schedulers.trampoline());
RxJavaPlugins.setComputationSchedulerHandler(
scheduler J> Schedulers.trampoline());
RxJavaPlugins.setNewThreadSchedulerHandler(
scheduler J> Schedulers.trampoline());
try {
base.evaluate();
} finally {
RxJavaPlugins.reset();
}
}
};
}
}
TEST SUBSCRIBER
public class TrampolineSchedulersRule implements TestRule {
@Override
public Statement apply(final Statement base, Description description) {
return new Statement() {
@Override public void evaluate() throws Throwable {
RxJavaPlugins.setIoSchedulerHandler(
scheduler J> Schedulers.trampoline());
RxJavaPlugins.setComputationSchedulerHandler(
scheduler J> Schedulers.trampoline());
RxJavaPlugins.setNewThreadSchedulerHandler(
scheduler J> Schedulers.trampoline());
try {
base.evaluate();
} finally {
RxJavaPlugins.reset();
}
}
};
}
}
TIME CONTROL
Observable<Integer> externalObservable = Observable.timer(10, TimeUnit.SECONDS)
.flatMap(ignore J> Observable.just(1, 2));
externalObservable.test()
.await()
.assertNoErrors()
.assertComplete()
.assertResult(1, 2)
.assertNever(3);
TIME CONTROL
@Test public void subscriberTest() throws InterruptedException {
Observable<Integer> externalObservable = Observable.timer(10, TimeUnit.SECONDS)
.flatMap(ignore J> Observable.just(1, 2));
TestObserver<Integer> testObserver = externalObservable.test();
testObserver.assertNoValues();
testObserver.await()
.assertNoErrors()
.assertComplete()
.assertResult(1, 2)
.assertNever(3);
}
TIME CONTROL
@Rule
public TestSchedulersRule testSchedulerRule = new TestSchedulersRule();
private TestScheduler testScheduler = testSchedulerRule.testScheduler;
@Test public void subscriberTest() throws InterruptedException {
Observable<Integer> externalObservable = Observable.timer(10, TimeUnit.SECONDS)
.flatMap(ignore J> Observable.just(1, 2));
TestObserver<Integer> testObserver = externalObservable.test();
testObserver.assertNoValues();
testScheduler.advanceTimeBy(10, TimeUnit.SECONDS);
testObserver
.assertNoErrors()
.assertComplete()
.assertResult(1, 2)
.assertNever(3);
}
TEXT
public class TestSchedulersRule implements TestRule {
TestScheduler testScheduler = new TestScheduler();
@Override
public Statement apply(final Statement base, Description description) {
return new Statement() {
@Override public void evaluate() throws Throwable {
RxJavaPlugins.setIoSchedulerHandler(
scheduler J> testScheduler);
RxJavaPlugins.setComputationSchedulerHandler(
scheduler J> testScheduler);
RxJavaPlugins.setNewThreadSchedulerHandler(
scheduler J> testScheduler);
try {
base.evaluate();
} finally {
RxJavaPlugins.reset();
}
}
};
}
}
THANKS
@STEPANGO
90seconds.tv

Mais conteúdo relacionado

Mais procurados

Registro de venta
Registro de ventaRegistro de venta
Registro de venta
lupe ga
 
並行処理プログラミングの深淵~Java仮想マシン仕様 スレッドとロック~
並行処理プログラミングの深淵~Java仮想マシン仕様 スレッドとロック~並行処理プログラミングの深淵~Java仮想マシン仕様 スレッドとロック~
並行処理プログラミングの深淵~Java仮想マシン仕様 スレッドとロック~
Kazuhiro Eguchi
 
Functional Reactive Programming / Compositional Event Systems
Functional Reactive Programming / Compositional Event SystemsFunctional Reactive Programming / Compositional Event Systems
Functional Reactive Programming / Compositional Event Systems
Leonardo Borges
 

Mais procurados (20)

Rxjava meetup presentation
Rxjava meetup presentationRxjava meetup presentation
Rxjava meetup presentation
 
Rx java testing patterns
Rx java testing patternsRx java testing patterns
Rx java testing patterns
 
Advanced patterns in asynchronous programming
Advanced patterns in asynchronous programmingAdvanced patterns in asynchronous programming
Advanced patterns in asynchronous programming
 
Fine grain process control 2nd nov
Fine grain process control 2nd novFine grain process control 2nd nov
Fine grain process control 2nd nov
 
Iniciación rx java
Iniciación rx javaIniciación rx java
Iniciación rx java
 
Good Tests Bad Tests
Good Tests Bad TestsGood Tests Bad Tests
Good Tests Bad Tests
 
OTcl and C++ linkages in NS2
OTcl and C++ linkages in NS2OTcl and C++ linkages in NS2
OTcl and C++ linkages in NS2
 
Async Testing giving you a sinking feeling
Async Testing giving you a sinking feelingAsync Testing giving you a sinking feeling
Async Testing giving you a sinking feeling
 
Dagger & rxjava & retrofit
Dagger & rxjava & retrofitDagger & rxjava & retrofit
Dagger & rxjava & retrofit
 
Registro de venta
Registro de ventaRegistro de venta
Registro de venta
 
Cascadia.js: Don't Cross the Streams
Cascadia.js: Don't Cross the StreamsCascadia.js: Don't Cross the Streams
Cascadia.js: Don't Cross the Streams
 
並行処理プログラミングの深淵~Java仮想マシン仕様 スレッドとロック~
並行処理プログラミングの深淵~Java仮想マシン仕様 スレッドとロック~並行処理プログラミングの深淵~Java仮想マシン仕様 スレッドとロック~
並行処理プログラミングの深淵~Java仮想マシン仕様 スレッドとロック~
 
Functional Reactive Programming / Compositional Event Systems
Functional Reactive Programming / Compositional Event SystemsFunctional Reactive Programming / Compositional Event Systems
Functional Reactive Programming / Compositional Event Systems
 
devday2012
devday2012devday2012
devday2012
 
Preparation for mit ose lab4
Preparation for mit ose lab4Preparation for mit ose lab4
Preparation for mit ose lab4
 
Android TDD & CI
Android TDD & CIAndroid TDD & CI
Android TDD & CI
 
Think Async: Asynchronous Patterns in NodeJS
Think Async: Asynchronous Patterns in NodeJSThink Async: Asynchronous Patterns in NodeJS
Think Async: Asynchronous Patterns in NodeJS
 
Introduction to Unit Testing (Part 2 of 2)
Introduction to Unit Testing (Part 2 of 2)Introduction to Unit Testing (Part 2 of 2)
Introduction to Unit Testing (Part 2 of 2)
 
Async JavaScript in ES7
Async JavaScript in ES7Async JavaScript in ES7
Async JavaScript in ES7
 
Fighting async JavaScript (CSP)
Fighting async JavaScript (CSP)Fighting async JavaScript (CSP)
Fighting async JavaScript (CSP)
 

Semelhante a rxJava 2 tips and tricks

Test-driven Development no Rails
Test-driven Development no RailsTest-driven Development no Rails
Test-driven Development no Rails
elliando dias
 
Test-driven Development no Rails - Começando com o pé direito
Test-driven Development no Rails - Começando com o pé direitoTest-driven Development no Rails - Começando com o pé direito
Test-driven Development no Rails - Começando com o pé direito
Nando Vieira
 

Semelhante a rxJava 2 tips and tricks (20)

Rx java2 - Should I use it?
Rx java2 - Should I use it?Rx java2 - Should I use it?
Rx java2 - Should I use it?
 
Akka.NET streams and reactive streams
Akka.NET streams and reactive streamsAkka.NET streams and reactive streams
Akka.NET streams and reactive streams
 
Rx workshop
Rx workshopRx workshop
Rx workshop
 
Taming Asynchrony using RxJS
Taming Asynchrony using RxJSTaming Asynchrony using RxJS
Taming Asynchrony using RxJS
 
Reactive Programming on Android
Reactive Programming on AndroidReactive Programming on Android
Reactive Programming on Android
 
A Playful Introduction to Rx
A Playful Introduction to RxA Playful Introduction to Rx
A Playful Introduction to Rx
 
2 презентация rx java+android
2 презентация rx java+android2 презентация rx java+android
2 презентация rx java+android
 
Understanding reactive programming with microsoft reactive extensions
Understanding reactive programming  with microsoft reactive extensionsUnderstanding reactive programming  with microsoft reactive extensions
Understanding reactive programming with microsoft reactive extensions
 
RxJava on Android
RxJava on AndroidRxJava on Android
RxJava on Android
 
RxJava и Android. Плюсы, минусы, подводные камни
RxJava и Android. Плюсы, минусы, подводные камниRxJava и Android. Плюсы, минусы, подводные камни
RxJava и Android. Плюсы, минусы, подводные камни
 
Saving lives with rx java
Saving lives with rx javaSaving lives with rx java
Saving lives with rx java
 
Test-driven Development no Rails
Test-driven Development no RailsTest-driven Development no Rails
Test-driven Development no Rails
 
Animation in Java
Animation in JavaAnimation in Java
Animation in Java
 
RxJava 2 Reactive extensions for the JVM
RxJava 2  Reactive extensions for the JVMRxJava 2  Reactive extensions for the JVM
RxJava 2 Reactive extensions for the JVM
 
Clojure functions midje
Clojure functions midjeClojure functions midje
Clojure functions midje
 
Reactive Programming with RxSwift
Reactive Programming with RxSwiftReactive Programming with RxSwift
Reactive Programming with RxSwift
 
Test-driven Development no Rails - Começando com o pé direito
Test-driven Development no Rails - Começando com o pé direitoTest-driven Development no Rails - Começando com o pé direito
Test-driven Development no Rails - Começando com o pé direito
 
How to Think in RxJava Before Reacting
How to Think in RxJava Before ReactingHow to Think in RxJava Before Reacting
How to Think in RxJava Before Reacting
 
TLA+ and PlusCal / An engineer's perspective
TLA+ and PlusCal / An engineer's perspectiveTLA+ and PlusCal / An engineer's perspective
TLA+ and PlusCal / An engineer's perspective
 
Reactive x
Reactive xReactive x
Reactive x
 

Último

Hospital management system project report.pdf
Hospital management system project report.pdfHospital management system project report.pdf
Hospital management system project report.pdf
Kamal Acharya
 
Call Girls in South Ex (delhi) call me [🔝9953056974🔝] escort service 24X7
Call Girls in South Ex (delhi) call me [🔝9953056974🔝] escort service 24X7Call Girls in South Ex (delhi) call me [🔝9953056974🔝] escort service 24X7
Call Girls in South Ex (delhi) call me [🔝9953056974🔝] escort service 24X7
9953056974 Low Rate Call Girls In Saket, Delhi NCR
 
Cara Menggugurkan Sperma Yang Masuk Rahim Biyar Tidak Hamil
Cara Menggugurkan Sperma Yang Masuk Rahim Biyar Tidak HamilCara Menggugurkan Sperma Yang Masuk Rahim Biyar Tidak Hamil
Cara Menggugurkan Sperma Yang Masuk Rahim Biyar Tidak Hamil
Cara Menggugurkan Kandungan 087776558899
 

Último (20)

Design For Accessibility: Getting it right from the start
Design For Accessibility: Getting it right from the startDesign For Accessibility: Getting it right from the start
Design For Accessibility: Getting it right from the start
 
Online electricity billing project report..pdf
Online electricity billing project report..pdfOnline electricity billing project report..pdf
Online electricity billing project report..pdf
 
Employee leave management system project.
Employee leave management system project.Employee leave management system project.
Employee leave management system project.
 
Hostel management system project report..pdf
Hostel management system project report..pdfHostel management system project report..pdf
Hostel management system project report..pdf
 
Generative AI or GenAI technology based PPT
Generative AI or GenAI technology based PPTGenerative AI or GenAI technology based PPT
Generative AI or GenAI technology based PPT
 
Wadi Rum luxhotel lodge Analysis case study.pptx
Wadi Rum luxhotel lodge Analysis case study.pptxWadi Rum luxhotel lodge Analysis case study.pptx
Wadi Rum luxhotel lodge Analysis case study.pptx
 
Moment Distribution Method For Btech Civil
Moment Distribution Method For Btech CivilMoment Distribution Method For Btech Civil
Moment Distribution Method For Btech Civil
 
A CASE STUDY ON CERAMIC INDUSTRY OF BANGLADESH.pptx
A CASE STUDY ON CERAMIC INDUSTRY OF BANGLADESH.pptxA CASE STUDY ON CERAMIC INDUSTRY OF BANGLADESH.pptx
A CASE STUDY ON CERAMIC INDUSTRY OF BANGLADESH.pptx
 
Hospital management system project report.pdf
Hospital management system project report.pdfHospital management system project report.pdf
Hospital management system project report.pdf
 
Navigating Complexity: The Role of Trusted Partners and VIAS3D in Dassault Sy...
Navigating Complexity: The Role of Trusted Partners and VIAS3D in Dassault Sy...Navigating Complexity: The Role of Trusted Partners and VIAS3D in Dassault Sy...
Navigating Complexity: The Role of Trusted Partners and VIAS3D in Dassault Sy...
 
Engineering Drawing focus on projection of planes
Engineering Drawing focus on projection of planesEngineering Drawing focus on projection of planes
Engineering Drawing focus on projection of planes
 
Bhubaneswar🌹Call Girls Bhubaneswar ❤Komal 9777949614 💟 Full Trusted CALL GIRL...
Bhubaneswar🌹Call Girls Bhubaneswar ❤Komal 9777949614 💟 Full Trusted CALL GIRL...Bhubaneswar🌹Call Girls Bhubaneswar ❤Komal 9777949614 💟 Full Trusted CALL GIRL...
Bhubaneswar🌹Call Girls Bhubaneswar ❤Komal 9777949614 💟 Full Trusted CALL GIRL...
 
COST-EFFETIVE and Energy Efficient BUILDINGS ptx
COST-EFFETIVE  and Energy Efficient BUILDINGS ptxCOST-EFFETIVE  and Energy Efficient BUILDINGS ptx
COST-EFFETIVE and Energy Efficient BUILDINGS ptx
 
Computer Lecture 01.pptxIntroduction to Computers
Computer Lecture 01.pptxIntroduction to ComputersComputer Lecture 01.pptxIntroduction to Computers
Computer Lecture 01.pptxIntroduction to Computers
 
PE 459 LECTURE 2- natural gas basic concepts and properties
PE 459 LECTURE 2- natural gas basic concepts and propertiesPE 459 LECTURE 2- natural gas basic concepts and properties
PE 459 LECTURE 2- natural gas basic concepts and properties
 
School management system project Report.pdf
School management system project Report.pdfSchool management system project Report.pdf
School management system project Report.pdf
 
Call Girls in South Ex (delhi) call me [🔝9953056974🔝] escort service 24X7
Call Girls in South Ex (delhi) call me [🔝9953056974🔝] escort service 24X7Call Girls in South Ex (delhi) call me [🔝9953056974🔝] escort service 24X7
Call Girls in South Ex (delhi) call me [🔝9953056974🔝] escort service 24X7
 
Cara Menggugurkan Sperma Yang Masuk Rahim Biyar Tidak Hamil
Cara Menggugurkan Sperma Yang Masuk Rahim Biyar Tidak HamilCara Menggugurkan Sperma Yang Masuk Rahim Biyar Tidak Hamil
Cara Menggugurkan Sperma Yang Masuk Rahim Biyar Tidak Hamil
 
FEA Based Level 3 Assessment of Deformed Tanks with Fluid Induced Loads
FEA Based Level 3 Assessment of Deformed Tanks with Fluid Induced LoadsFEA Based Level 3 Assessment of Deformed Tanks with Fluid Induced Loads
FEA Based Level 3 Assessment of Deformed Tanks with Fluid Induced Loads
 
HAND TOOLS USED AT ELECTRONICS WORK PRESENTED BY KOUSTAV SARKAR
HAND TOOLS USED AT ELECTRONICS WORK PRESENTED BY KOUSTAV SARKARHAND TOOLS USED AT ELECTRONICS WORK PRESENTED BY KOUSTAV SARKAR
HAND TOOLS USED AT ELECTRONICS WORK PRESENTED BY KOUSTAV SARKAR
 

rxJava 2 tips and tricks

  • 2. ABOUT ME ▸ Android developer since 2008 ▸ Lead Android Engineer @ 90Seconds.tv ▸ Kotlin and Rx addict ▸ RxKotlin contributor ▸ RxDataBindings author
  • 3. Event Iterable Observable retrieve data T next() onNext(T) discover error throw Exception onError(Exception) complete !hasNext() onCompleted() transform fromIterbale() toList() SHORTEST RX INTRO EVER
  • 4. 1.0 VS 2.0 ▸ Mar 2018 - end of rxJava1 support ▸ Better performance ▸ Lower memory consumption ▸ Can’t use null ▸ Reactive-Streams based ▸ Maybe, Flowable
  • 5. OBSERVABLE AND FRIENDS ▸ Flowable: 0..N flows, supporting Reactive-Streams and backpressure ▸ Observable: 0..N flows, no backpressure ▸ Single: a flow of exactly 1 item or an error ▸ Completable: a flow without items but only a completion or error signal ▸ Maybe: a flow with no items, exactly one item or an error
  • 6. HOW TO DEAL WITH NULLS ▸ Null object pattern ▸ Optional ▸ State wrappers
  • 7. NULL OBJECT PATTERN interface Animal { void makeSound(); } class Dog implements Animal { public void makeSound() { System.out.println("woof!"); } } enum NullAnimal implements Animal { INSTANCE; public void makeSound() {}; } void execute() { List<Animal> animals = Arrays.asList(NullAnimal.INSTANCE, new Dog()); Observable.fromIterable(animals) .filter(animal J> animal != NullAnimal.INSTANCE) .subscribe(AnimalKLmakeSound); }
  • 8. STREAM OF OPTIONAL VALUES interface Animal { void makeSound(); } class Dog implements Animal { public void makeSound() { System.out.println("woof!"); } } public void execute() { List<Optional<Animal>> animals = Arrays.asList( Optional.<Animal>empty(), Optional.of(new Dog()) ); Observable.fromIterable(animals) .filter(OptionalKLisPresent) .map(OptionalKLget) .subscribe(AnimalKLmakeSound); }
  • 9. STREAM OF STATES class AnimalStateSuccess implements AnimalState { Animal animal; AnimalStateSuccess(Animal animal) { this.animal = animal; } @Override public boolean hasAnimal() { return true;} @Override public Animal animal() { return animal; } @Override public String errorMsg() { return null; } } enum AnimalStateError implements AnimalState { INSTANCE; @Override public boolean hasAnimal() { return false;} @Override public Animal animal() { return null; } @Override public String errorMsg() { return "We lost him"; } } public void execute() { List<AnimalState> animals = Arrays.asList( AnimalStateError.INSTANCE, new AnimalStateSuccess(new Dog()) ); Observable.fromIterable(animals) .filter(AnimalStateKLhasAnimal) .map(AnimalStateKLanimal) .subscribe(AnimalKLmakeSound); }
  • 10. TESTING IS EASY ▸ Blocking calls ▸ TestSubscriber TestObserver ▸ RxJavaPlugins ▸ await()/awaitTerminalEvent() ▸ TestScheduler
  • 11. BLOCKING CALLS Observable<Integer> observable = Observable.just(1, 2); int first = observable.blockingFirst(); assertEquals(first, 1); int last = observable.blockingLast(); assertEquals(last, 2); Iterable<Integer> integers = observable.blockingIterable(); int sum = 0; for (Integer integer : integers) sum += integer; assertEquals(sum, 3);
  • 13. TEST SUBSCRIBER Observable.timer(1, TimeUnit.SECONDS) .flatMap(ignore J> Observable.just(1, 2)) .test() .assertNoErrors() .assertComplete() .assertResult(1, 2) .assertNever(3);
  • 14. TEST SUBSCRIBER Observable.timer(1, TimeUnit.SECONDS) .flatMap(ignore J> Observable.just(1, 2)) .test() .assertNoErrors() .assertComplete() .assertResult(1, 2) .assertNever(3); FAIL
  • 15. TEST SUBSCRIBER Observable.timer(1, TimeUnit.SECONDS) .flatMap(ignore J> Observable.just(1, 2)) .test() .await() .assertNoErrors() .assertComplete() .assertResult(1, 2) .assertNever(3);
  • 16. AWAIT TERMINAL EVENT boolean hasTerminalEvent = Observable.timer(1, TimeUnit.SECONDS) .flatMap(ignore J> Observable.just(1, 2)) .test() .awaitTerminalEvent(500, TimeUnit.MILLISECONDS); assertFalse(hasTerminalEvent);
  • 17. PREVENT FROM FAILING Observable.timer(1, TimeUnit.SECONDS) .flatMap(ignore J> Observable.just(1, 2)) .test() .assertNoErrors() .assertComplete() .assertResult(1, 2) .assertNever(3);
  • 18. UNIT TEST RULE @Rule final TrampolineSchedulersRule schedulers = new TrampolineSchedulersRule(); @Test public void observerTest() throws InterruptedException { Observable.timer(1, TimeUnit.SECONDS) .flatMap(ignore J> Observable.just(1, 2)) .test() .assertNoErrors() .assertComplete() .assertResult(1, 2) .assertNever(3); }
  • 19. TEST SUBSCRIBER public class TrampolineSchedulersRule implements TestRule { @Override public Statement apply(final Statement base, Description description) { return new Statement() { @Override public void evaluate() throws Throwable { RxJavaPlugins.setIoSchedulerHandler( scheduler J> Schedulers.trampoline()); RxJavaPlugins.setComputationSchedulerHandler( scheduler J> Schedulers.trampoline()); RxJavaPlugins.setNewThreadSchedulerHandler( scheduler J> Schedulers.trampoline()); try { base.evaluate(); } finally { RxJavaPlugins.reset(); } } }; } }
  • 20. TEST SUBSCRIBER public class TrampolineSchedulersRule implements TestRule { @Override public Statement apply(final Statement base, Description description) { return new Statement() { @Override public void evaluate() throws Throwable { RxJavaPlugins.setIoSchedulerHandler( scheduler J> Schedulers.trampoline()); RxJavaPlugins.setComputationSchedulerHandler( scheduler J> Schedulers.trampoline()); RxJavaPlugins.setNewThreadSchedulerHandler( scheduler J> Schedulers.trampoline()); try { base.evaluate(); } finally { RxJavaPlugins.reset(); } } }; } }
  • 21. TIME CONTROL Observable<Integer> externalObservable = Observable.timer(10, TimeUnit.SECONDS) .flatMap(ignore J> Observable.just(1, 2)); externalObservable.test() .await() .assertNoErrors() .assertComplete() .assertResult(1, 2) .assertNever(3);
  • 22. TIME CONTROL @Test public void subscriberTest() throws InterruptedException { Observable<Integer> externalObservable = Observable.timer(10, TimeUnit.SECONDS) .flatMap(ignore J> Observable.just(1, 2)); TestObserver<Integer> testObserver = externalObservable.test(); testObserver.assertNoValues(); testObserver.await() .assertNoErrors() .assertComplete() .assertResult(1, 2) .assertNever(3); }
  • 23. TIME CONTROL @Rule public TestSchedulersRule testSchedulerRule = new TestSchedulersRule(); private TestScheduler testScheduler = testSchedulerRule.testScheduler; @Test public void subscriberTest() throws InterruptedException { Observable<Integer> externalObservable = Observable.timer(10, TimeUnit.SECONDS) .flatMap(ignore J> Observable.just(1, 2)); TestObserver<Integer> testObserver = externalObservable.test(); testObserver.assertNoValues(); testScheduler.advanceTimeBy(10, TimeUnit.SECONDS); testObserver .assertNoErrors() .assertComplete() .assertResult(1, 2) .assertNever(3); }
  • 24. TEXT public class TestSchedulersRule implements TestRule { TestScheduler testScheduler = new TestScheduler(); @Override public Statement apply(final Statement base, Description description) { return new Statement() { @Override public void evaluate() throws Throwable { RxJavaPlugins.setIoSchedulerHandler( scheduler J> testScheduler); RxJavaPlugins.setComputationSchedulerHandler( scheduler J> testScheduler); RxJavaPlugins.setNewThreadSchedulerHandler( scheduler J> testScheduler); try { base.evaluate(); } finally { RxJavaPlugins.reset(); } } }; } }