Guest User

Untitled

a guest
Oct 12th, 2018
145
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.69 KB | None | 0 0
  1. @PerFragment
  2. class SomeViewModel @Inject constructor(private val someActionUseCase: SomeActionUseCase,
  3. someUpdateStateUseCase: SomeUpdateStateUseCase) : ViewModel() {
  4.  
  5. private val someState = MutableLiveData<SomeState>()
  6.  
  7. private val stateSubscription: Disposable
  8.  
  9. // region Lifecycle
  10. init {
  11. stateSubscription = someUpdateStateUseCase.state()
  12. .subscribeIoObserveMain() // extension function
  13. .subscribe { newState ->
  14. someState.value = newState
  15. })
  16. }
  17.  
  18. override fun onCleared() {
  19. stateSubscription.dispose()
  20.  
  21. super.onCleared()
  22. }
  23. // endregion
  24.  
  25. // region Public Functions
  26. fun someState() = someState
  27.  
  28. fun someAction(someValue: Boolean) {
  29. val someNewValue = if (someValue) "This" else "That"
  30.  
  31. someActionUseCase.someAction(someNewValue)
  32. }
  33. // endregion
  34. }
  35.  
  36. @Singleton
  37. class UpdateSomeStateUseCase @Inject constructor(
  38. private var state: SomeState = initialState) {
  39.  
  40. private val statePublisher: PublishProcessor<SomeState> =
  41. PublishProcessor.create()
  42.  
  43. fun update(state: SomeState) {
  44. this.state = state
  45.  
  46. statePublisher.onNext(state)
  47. }
  48.  
  49. fun state(): Observable<SomeState> = statePublisher.toObservable()
  50. .startWith(state)
  51. }
  52.  
  53. @RunWith(JUnitPlatform::class)
  54. class SomeViewModelTest : SubjectSpek<SomeViewModel>({
  55.  
  56. instantTaskExecutorRuleStart()
  57.  
  58. var mockSomeActionUseCase = mock<SomeActionUseCase>()
  59. var mockSomeUpdateStateUseCase = mock<SomeUpdateStateUseCase>()
  60.  
  61. var liveState = MutableLiveData<SomeState>()
  62.  
  63. val initialState = SomeState(initialValue)
  64. val newState = SomeState(newValue)
  65.  
  66. val behaviorSubject = BehaviorSubject.createDefault(initialState)
  67.  
  68. subject {
  69. mockSomeActionUseCase = mock()
  70. mockSomeUpdateStateUseCase = mock()
  71.  
  72. whenever(mockSomeUpdateStateUseCase.state()).thenReturn(behaviorSubject)
  73.  
  74. SomeViewModel(mockSomeActionUseCase, mockSomeUpdateStateUseCase).apply {
  75. liveState = state() as MutableLiveData<SomeState>
  76. }
  77. }
  78.  
  79. beforeGroup { setTestRxAndLiveData() }
  80. afterGroup { resetTestRxAndLiveData(subject) }
  81.  
  82. context("some screen") {
  83. given("the action to open the screen") {
  84. on("screen opened") {
  85. subject
  86. behaviorSubject.startWith(initialState)
  87.  
  88. it("displays the initial state") {
  89. assertEquals(liveState.value, initialState)
  90. }
  91. }
  92. }
  93.  
  94. given("some setup") {
  95. on("some action") {
  96. it("does something") {
  97. subject.doSomething(someValue)
  98.  
  99. verify(mockSomeUpdateStateUseCase).someAction(someOtherValue)
  100. }
  101. }
  102.  
  103. on("action updating the state") {
  104. it("displays new state") {
  105. behaviorSubject.onNext(newState)
  106.  
  107. assertEquals(liveState.value, newState)
  108. }
  109. }
  110. }
  111. }
  112. }
  113.  
  114. var observable = Observable.just(initialState)
  115. ...
  116. whenever(mockSomeUpdateStateUseCase.state()).thenReturn(observable)
  117. ...
  118. observable = Observable.just(newState)
  119. assertEquals(liveState.value, newState)
  120.  
  121. val behaviorSubject = BehaviorSubject.createDefault(initialState)
  122. ...
  123. whenever(mockSomeUpdateStateUseCase.state()).thenReturn(behaviorSubject)
  124. ...
  125. behaviorSubject.onNext(newState)
  126. assertEquals(liveState.value, newState)
  127.  
  128. fun instantTaskExecutorRuleStart() =
  129. ArchTaskExecutor.getInstance().setDelegate(object : TaskExecutor() {
  130. override fun executeOnDiskIO(runnable: Runnable) {
  131. runnable.run()
  132. }
  133.  
  134. override fun isMainThread(): Boolean {
  135. return true
  136. }
  137.  
  138. override fun postToMainThread(runnable: Runnable) {
  139. runnable.run()
  140. }
  141. })
  142.  
  143. fun instantTaskExecutorRuleFinish() = ArchTaskExecutor.getInstance().setDelegate(null)
  144.  
  145. fun setRxSchedulersTrampolineOnMain() = RxAndroidPlugins.setInitMainThreadSchedulerHandler { Schedulers.trampoline() }
  146.  
  147. fun setTestRxAndLiveData() {
  148. setRxSchedulersTrampolineOnMain()
  149. instantTaskExecutorRuleStart()
  150. }
  151.  
  152. fun resetTestRxAndLiveData() {
  153. RxAndroidPlugins.reset()
  154. instantTaskExecutorRuleFinish()
  155. }
  156.  
  157. fun <T> Observable<T>.subscribeIoObserveMain(): Observable<T> =
  158. subscribeOnIoThread().observeOnMainThread()
  159.  
  160. fun <T> Observable<T>.subscribeOnIoThread(): Observable<T> = subscribeOn(Schedulers.io())
  161.  
  162. fun <T> Observable<T>.observeOnMainThread(): Observable<T> =
  163. observeOn(AndroidSchedulers.mainThread())
Add Comment
Please, Sign In to add comment