package Ġto ky o . over software . book explorer Ċ Ċ import Ġandroidx . arch . core . executor . testing . Instant Task Executor Rule Ċ import Ġandroidx . lifecycle . Observer Ċ import Ġio . reactivex . rx java 3 . core . Observable Ċ import Ġio . reactivex . rx java 3 . core . Single Ċ import Ġorg . junit . Assert Ċ import Ġorg . junit . Rule Ċ import Ġorg . junit . Test Ċ import Ġorg . junit . rules . Test Rule Ċ import Ġto ky o . over software . book explorer . entity . Books Ċ import Ġto ky o . over software . book explorer . entity . Display able Book Ċ import Ġto ky o . over software . book explorer . model . repository . Books Repository Ċ import Ġto ky o . over software . book explorer . view model . Search ViewModel Ċ import Ġjava . util . concurrent . Count DownLatch Ċ import Ġjava . util . concurrent . TimeUnit Ċ import Ġjava . util . concurrent . TimeoutException Ċ Ċ /** Ċ Ġ* Ġ éĿŀ åĲĮ æľŁ ãĥĨãĤ¹ãĥĪ çĶ¨ ãģ® Observer Ċ Ġ* ĠMutable LiveData # post Value Ġãģ® ãĤĪãģĨ ãģª éĿŀ åĲĮ æľŁ ãģ§ å¤ī ãĤı ãĤĬ ãģĨ ãĤĭ åĩ¦çĲĨ ãģ® åł´åĲĪãģ¯ JUnit ãģ§ ãģĿãģ® ãģ¾ ãģ¾ ãĥĨãĤ¹ãĥĪ ãģĮ åĩºæĿ¥ ãģªãģĦ ãģ®ãģ§ Ċ Ġ* ĠCount DownLatch ãĤĴ åĪ©çĶ¨ ãģĹãģŁ Observer ãĤĴä½ľæĪĲ ãģĻãĤĭ Ċ Ġ*/ Ċ class ĠTest Observer < T >( count : ĠInt Ġ= Ġ 1 ) Ġ: ĠObserver < T > Ġ{ ĊĊĠĠĠ Ġprivate Ġval Ġl atch : ĠCount DownLatch Ġ= ĠCount DownLatch ( count ) ĊĊĠĠĠ Ġprivate Ġval Ġvalues Ġ= Ġmutable ListOf < T ?> () ĊĊĠĠĠ Ġoverride Ġfun ĠonChanged ( t : ĠT ?) Ġ{ ĊĠĠĠĠĠĠĠ Ġvalues . add ( t ) ĊĠĠĠĠĠĠĠ Ġl atch . count Down () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġget (): ĠT ? Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( values . size Ġ== Ġ 0 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠIllegalStateException (" on Changed Ġis Ġnot Ġcalled .") ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġreturn Ġvalues [ values . size Ġ- Ġ 1 ] ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġawait ( timeout : ĠLong Ġ= Ġ 1 , Ġunit : ĠTimeUnit Ġ= ĠTimeUnit . SECONDS ) Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ(! latch . await ( timeout , Ġunit )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠTimeout Exception () ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} Ċ } Ċ Ċ class ĠViewModel Test Ġ{ ĊĊĠĠĠ Ġ@ Rule ĊĠĠĠ Ġ@ Jvm Field ĊĠĠĠ Ġval Ġrule : ĠTest Rule Ġ= ĠInstant Task Executor Rule () ĊĊĠĠĠ Ġprivate Ġclass ĠEmpty Data Repository Ġ: ĠBooks Repository Ġ{ ĊĠĠĠĠĠĠĠ Ġoverride Ġfun Ġfind Books ( search Keyword : ĠString ): ĠSingle < Books > Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĠSingle . just ( Books ( kind Ġ= Ġ"", Ġtotal Items Ġ= Ġ 0 , Ġitems Ġ= Ġempty List ())) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġclass ĠInvalid Data Repository Ġ: ĠBooks Repository Ġ{ ĊĠĠĠĠĠĠĠ Ġoverride Ġfun Ġfind Books ( search Keyword : ĠString ): ĠSingle < Books > Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĠSingle . error ( Throwable (" Invalid ĠResponse ")) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġclass ĠNormal Data Repository Ġ: ĠBooks Repository Ġ{ ĊĠĠĠĠĠĠĠ Ġoverride Ġfun Ġfind Books ( search Keyword : ĠString ): ĠSingle < Books > Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĠSingle . just ( Constants . mock Book ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Test ĊĠĠĠ Ġfun Ġ` Validate Ġsuccess ĠEmpty ĠResponse `() Ġ{ ĊĠĠĠĠĠĠĠ Ġval ĠviewModel Ġ= ĠSearch ViewModel ( repository Ġ= ĠEmpty Data Repository ()) ĊĠĠĠĠĠĠĠ Ġ// Ġ å¤īæķ° åĪĿ æľŁ åĮĸ æĻĤ , Ġæ ¤ ľç´¢ éĸĭå§ĭ æĻĤ , Ġæ ¤ ľç´¢ çµĤ äºĨ æĻĤ ãģ§ 3 åĽŀ åĢ¤ ãģĮ æµģ ãĤĮãĤĭ ãģ®ãģ§ 3 åĽŀ åĪĨ å¾ħ ãģ¤ ĊĠĠĠĠĠĠĠ Ġval Ġobserver Ġ= ĠTest Observer < List < Display able Book >>( count Ġ= Ġ 3 ) ĊĠĠĠĠĠĠĠ ĠviewModel . items . observe Fore ver ( observer ) ĊĠĠĠĠĠĠĠ ĠviewModel . on Search ( Observable . just (" example ")) ĊĠĠĠĠĠĠĠ Ġobserver . await () ĊĠĠĠĠĠĠĠ ĠAssert . assertEquals ( observer . get ()?. size , Ġ 0 ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Test ĊĠĠĠ Ġfun Ġ` Validate Ġsuccess ĠNormal ĠResponse `() Ġ{ ĊĠĠĠĠĠĠĠ Ġval ĠviewModel Ġ= ĠSearch ViewModel ( repository Ġ= ĠNormal Data Repository ()) ĊĠĠĠĠĠĠĠ Ġ// Ġ å¤īæķ° åĪĿ æľŁ åĮĸ æĻĤ , Ġæ ¤ ľç´¢ éĸĭå§ĭ æĻĤ , Ġæ ¤ ľç´¢ çµĤ äºĨ æĻĤ ãģ§ 3 åĽŀ åĢ¤ ãģĮ æµģ ãĤĮãĤĭ ãģ®ãģ§ 3 åĽŀ åĪĨ å¾ħ ãģ¤ ĊĠĠĠĠĠĠĠ Ġval Ġobserver Ġ= ĠTest Observer < List < Display able Book >>( count Ġ= Ġ 3 ) ĊĠĠĠĠĠĠĠ ĠviewModel . items . observe Fore ver ( observer ) ĊĠĠĠĠĠĠĠ ĠviewModel . on Search ( Observable . just (" example ")) ĊĠĠĠĠĠĠĠ Ġobserver . await () ĊĠĠĠĠĠĠĠ ĠAssert . assertEquals ( observer . get ()?. last ()?. title , Ġ" Example Book ") ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Test ĊĠĠĠ Ġfun Ġ` Validate ĠError ĠResponse `() Ġ{ ĊĠĠĠĠĠĠĠ Ġval ĠviewModel Ġ= ĠSearch ViewModel ( repository Ġ= ĠInvalid Data Repository ()) ĊĠĠĠĠĠĠĠ Ġ// Ġ å¤īæķ° åĪĿ æľŁ åĮĸ æĻĤ , Ġæ ¤ ľç´¢ éĸĭå§ĭ æĻĤ , ĠãĤ¨ ãĥ© ãĥ¼ ãģ§ 3 åĽŀ åĢ¤ ãģĮ æµģ ãĤĮãĤĭ ãģ®ãģ§ 3 åĽŀ åĪĨ å¾ħ ãģ¤ ĊĠĠĠĠĠĠĠ Ġval Ġobserver Ġ= ĠTest Observer < Boolean >( count Ġ= Ġ 3 ) ĊĠĠĠĠĠĠĠ ĠviewModel . onError . observe Fore ver ( observer ) ĊĠĠĠĠĠĠĠ ĠviewModel . on Search ( Observable . just (" example ")) ĊĠĠĠĠĠĠĠ ĠAssert . assertEquals ( observer . get (), Ġfalse ) ĊĠĠĠĠĠĠĠ Ġobserver . await () ĊĠĠĠĠĠĠĠ ĠAssert . assertEquals ( observer . get (), Ġtrue ) ĊĠĠĠ Ġ} Ċ }