Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Testing & RxJava2 (AppBuilders 2018)
Search
Sasa Sekulic
April 16, 2018
Programming
460
3
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Testing & RxJava2 (AppBuilders 2018)
With RxJava you can write some complex, multithreaded code - and testing it is easy!
Sasa Sekulic
April 16, 2018
More Decks by Sasa Sekulic
See All by Sasa Sekulic
Testing & RxJava2 (GrowIT Serbia 2018)
mrsasha
0
99
Management for developers v.2
mrsasha
0
72
Management for developers
mrsasha
1
230
Reactive programming on Android - why and how v2 (CodeMobile 2017)
mrsasha
0
130
Reactive programming on Android - why and how (Droidcon Krakow 2016)
mrsasha
0
300
Reactive programming on Android - why and how (Droidcon UK 2016)
mrsasha
6
560
Recipes in RxJava for Android, v.3
mrsasha
1
290
Recipes in RxJava for Android, v.2
mrsasha
3
1.4k
Recipes in RxJava for Android
mrsasha
7
1.7k
Other Decks in Programming
See All in Programming
AI駆動開発を妨げる技術的負債の解消アプローチ / ai-refactoring-approach
minodriven
16
8.3k
Agentic UI
manfredsteyer
PRO
0
210
エージェンティックRAGにAWSで入門しよう!
har1101
9
1.9k
Semantic Version 単位で戦略を柔軟に変えて、パッケージアップデートを自動化する
daitasu
1
320
決定論的オーケストレーションの設計と実装 / Design and Implementation of Deterministic Orchestration
nrslib
4
1.6k
AI時代のUIはどこへ行く?その2!
yusukebe
22
7.7k
その問い、本当に正しいですか?AI時代のエンジニアに必要な哲学と認知科学 / ai-philosophy-cognitive-science
minodriven
14
6.5k
メソッドのジェネリクスでGoの夢は広がるか? / Kyoto.go #65
utgwkk
3
1k
才能?センス?知らん、 続けたもん勝ちだ。-- 結婚・出産・癌を越えてなお、私がプロダクトを創り続ける理由
16bitidol
2
610
OS アップデート対応の取り組み方がもっと共有されてほしい
andpad
0
110
そのテスト、説明できますか?~LWテスト戦略FW~のご紹介
nakahara
0
180
Observability in Practice:Grafana 與 Edge Device SRE 的那些事
blueswen
0
180
Featured
See All Featured
Stop Working from a Prison Cell
hatefulcrawdad
274
21k
Responsive Adventures: Dirty Tricks From The Dark Corners of Front-End
smashingmag
254
22k
We Analyzed 250 Million AI Search Results: Here's What I Found
joshbly
1
1.4k
Visual Storytelling: How to be a Superhuman Communicator
reverentgeek
2
570
Build The Right Thing And Hit Your Dates
maggiecrowley
39
3.2k
Paper Plane
katiecoart
PRO
1
52k
Leveraging Curiosity to Care for An Aging Population
cassininazir
1
300
Ethics towards AI in product and experience design
skipperchong
2
320
Redefining SEO in the New Era of Traffic Generation
szymonslowik
1
350
Building Adaptive Systems
keathley
44
3.1k
Un-Boring Meetings
codingconduct
0
330
Bioeconomy Workshop: Dr. Julius Ecuru, Opportunities for a Bioeconomy in West Africa
akademiya2063
PRO
1
170
Transcript
None
None
test() Observable.just(1) .test() .assertValue(1) val subject = PublishSubject.create<Int>()
val subject = PublishSubject.create<Int>() subject.onNext(1) subject.test() .assertValueCount(1) .assertValue(1)
TestObserver val testObserver = Observable.just(1).test() testObserver.assertValue(1) val subject
= PublishSubject.create<Int>() val testObserver = subject.test() val testObserver = subject.test() subject.onNext(1) testObserver.assertValueCount(1) testObserver.assertValue(1) subject.onNext(2) testObserver.assertValueCount(2) testObserver.assertValues(1, 2)
Observable.just(1) .test() .assertValueCount(1) .assertValue(1) .assertValue({ it == 1 }) .assertNoValues()
.assertValuesOnly(1) Observable.just(1, 2) .test() .assertValueCount(2) .assertValues(1, 2) .assertValueAt(0, 1) .assertValueAt(0) { it == 1 } .assertNever(3)
Observable.just(1) .test() .assertTerminated() .assertComplete() .assertNoErrors() .assertSubscribed() .assertNotComplete() .assertNotTerminated() .assertNotTerminated() .assertEmpty()
.assertError(PaymentException("test")) .assertError(PaymentMethodNotSupportedException::class.java) .assertError({error -> error.cause == PaymentException("test")}) .assertErrorMessage("test")
assertResult() assertSubscribed().assertValues() .assertNoErrors().assertComplete() Observable.just(1, 2).test() .assertResult(1, 2) assertFailure()
assertSubscribed().assertValues() .assertError().assertNotComplete() Observable.error<Int>(RuntimeException("test")).test() .assertFailure(RuntimeException::class.java) .assertFailure(Predicate { it -> it == RuntimeException() }) .assertFailureAndMessage(RuntimeException::class.java, "test")
assertFailure() Observable.error<Int>(RuntimeException("test")) .startWith(Observable.just(1, 2)) .test() .assertFailure(RuntimeException::class.java, 1, 2) .assertFailure(RuntimeException::class.java)
.assertFailure(Predicate { it -> it == RuntimeException() }) .assertFailureAndMessage(RuntimeException::class.java, "test")
val zippedObservable1 = Observable.error<Int>(Throwable("error 1")) val zippedObservable2 = Observable.error<Int>(Throwable("error 2"))
Observable.zip(zippedObservable1, zippedObservable2, BiFunction({first: Observable.zip(zippedObservable1, zippedObservable2, BiFunction({first: Int, second: Int -> first + second})) .test() .assertErrorMessage("error 1") .assertErrorMessage("error 2")
Observable.just(1).test() .await() .await(1, TimeUnit.SECONDS) Observable.just(1).test() .awaitTerminalEvent() Observable.just(1, 2) Observable.just(1, 2)
.delay (2, TimeUnit.SECONDS) .test() .awaitDone(2, TimeUnit.SECONDS) .awaitCount(2, BaseTestConsumer.TestWaitStrategy.SLEEP_1000MS, 2000) .assertTimeout()
Schedulers Observable.just(1) .observeOn(Schedulers.io()) .test() .assertValue(1) Schedulers Schedulers
Schedulers
Schedulers RxJavaPlugins.setIoSchedulerHandler { Schedulers.trampoline() } Observable.just(1) .observeOn(Schedulers.io()) .test() .assertValue(1) Schedulers
Schedulers RxJavaPlugins.setIoSchedulerHandler { Schedulers.trampoline() } RxJavaPlugins.setComputationSchedulerHandler { Schedulers.trampoline() } RxJavaPlugins.setNewThreadSchedulerHandler { Schedulers.trampoline() } Schedulers RxAndroidPlugins.reset() RxAndroidPlugins.setInitMainThreadSchedulerHandler {Schedulers.trampoline()}
Schedulers @Rule class TrampolineSchedulerRule : TestRule { override fun apply(base:
Statement, d: Description): Statement { return object : Statement() { @Throws(Throwable::class) override fun evaluate() { RxJavaPlugins.setIoSchedulerHandler… try { base.evaluate() } finally { RxJavaPlugins.reset() } } } } }
Schedulers @Rule @Rule val schedulerRule = TrampolineSchedulerRule() https://medium.com/@fabioCollini/testing-asynchronous-rxjava-code-using-mockito-
8ad831a16877 https://www.infoq.com/articles/Testing-RxJava
Schedulers Schedulers interface SchedulerProvider { fun ui(): Scheduler fun computation():
Scheduler fun io(): Scheduler } class AppSchedulerProvider : SchedulerProvider { override fun ui() = AndroidSchedulers.mainThread() override fun computation() = Schedulers.computation() override fun io() = Schedulers.io() } class TrampolineSchedulerProvider : SchedulerProvider { override fun ui() = Schedulers.trampoline() override fun computation() = Schedulers.trampoline() override fun io() = Schedulers.trampoline() }
Schedulers class UsesSchedulerProvider (schedulers: SchedulerProvider) { … … }
fun methodWithWorker(scheduler: Scheduler): AtomicInteger { val counter = AtomicInteger() val
worker = scheduler.createWorker() worker.schedule({ counter.incrementAndGet() }) worker.schedule({ counter.incrementAndGet() }) return counter } val scheduler = TestScheduler() val counter = methodWithWorker(scheduler) Assert.assertEquals(2, counter.get()) testScheduler.triggerActions() Assert.assertEquals(2, counter.get())
TestScheduler val timedoutObservable = Observable.never<Int>() .timeout(5, TimeUnit.SECONDS) timedoutObservable.test() .assertError(TimeoutException::class.java) timeout()
timeout(5, TimeUnit.SECONDS) == timeout(5, TimeUnit.SECONDS, Schedulers.computation())
TestScheduler val scheduler = TestScheduler() val timedoutObservable = Observable.never<Int>() val
timedoutObservable = Observable.never<Int>() .timeout(5, TimeUnit.SECONDS, ,scheduler) advanceTimeBy() scheduler.advanceTimeBy(5, TimeUnit.SECONDS) timedoutObservable.test() .assertError(TimeoutException::class.java)
TestScheduler TestScheduler val scheduler = TestScheduler(2, TimeUnit.SECONDS) advanceTimeTo() Scheduler.advanceTimeTo(5, TimeUnit.SECONDS)
TestScheduler TestScheduler val currentTime = scheduler.now(TimeUnit.SECONDS)