例えば val liveData: LiveData<Int>
みたいな値があってそれのライフサイクルに応じた変化をテストしたい場合
なぜこんなことをしたいかというと、RxJava→LiveDataの変換をした際に、初期値が正しく設定されるかなどのテストをしたかったので、Lifecycleを利用する方法を調べた。
全体のテストコード
object LifecycleTest : Spek({
Feature("hoge機能") {
val lifeCycleObserver: LifecycleObserver by memoized { mockk<LifecycleObserver>() }
val lifeCycleOwner: LifecycleOwner by memoized { mockk<LifecycleOwner>() }
val lifeCycle: LifecycleRegistry by memoized { LifecycleRegistry(lifeCycleOwner) }
val observer: Observer<Int> by memoized { mockk<Observer<Int>>(relaxed = true) }
beforeEachTest {
every {
lifeCycleOwner.lifecycle
} returns lifeCycle
lifeCycle.addObserver(lifeCycleObserver)
}
Scenario("開始状態") {
Given("LiveDataを購読") {
liveData.observe(lifeCycleOwner, observer)
}
When("ライフサイクルを開始状態にする") {
lifeCycle.handleLifecycleEvent(Lifecycle.Event.ON_CREATE)
lifeCycle.handleLifecycleEvent(Lifecycle.Event.ON_START)
}
Then("期待値") {
verifySequence {
observer.onChanged(1)
}
}
}
}
})
Lifecycleの設定
Lifecycle関連のコード
val lifeCycleObserver: LifecycleObserver by memoized { mockk<LifecycleObserver>() }
val lifeCycleOwner: LifecycleOwner by memoized { mockk<LifecycleOwner>() }
val lifeCycle: LifecycleRegistry by memoized { LifecycleRegistry(lifeCycleOwner) }
beforeEachTest {
every {
lifeCycleOwner.lifecycle
} returns lifeCycle
lifeCycle.addObserver(lifeCycleObserver)
}
lifeCycleOwnerをLiveDataにわたすOwnerにし、 mockkで lifeCycleOwner.lifecycle
の戻り値を LifecycleRegistry
になるようにモック化
LifecycleRegistry
にObserverが1件も無いステータスを変化するロジックで以下のコード部分で mObserverMap.sizeが0になり、更新されなくなってしまうのでダミーで lifeCycle.addObserver(lifeCycleObserver)
している。
LifecycleRegistry.kt
private boolean isSynced() {
if (mObserverMap.size() == 0) {
return true;
}
State eldestObserverState = mObserverMap.eldest().getValue().mState;
State newestObserverState = mObserverMap.newest().getValue().mState;
return eldestObserverState == newestObserverState && mState == newestObserverState;
}
Lifecycleの設定
lifeCycle.handleLifecycleEvent(Lifecycle.Event.ON_CREATE)
lifeCycle.handleLifecycleEvent(Lifecycle.Event.ON_START)
こんな感じで lifeCycle.handleLifecycleEvent
を呼ぶことで状態遷移を起こすことができる。