LoginSignup
2
0

More than 3 years have passed since last update.

SpekでLifecycleを利用したテストをする方法

Posted at

例えば 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 を呼ぶことで状態遷移を起こすことができる。

2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0