본문 바로가기

Android/TDD(Test Driven Development, 테스트 주도 개발)

Turbine 없이 kotest에서 StateFlow, SharedFlow 테스트 하기, Unit Test

반응형

바쁜 분들

// state flow
viewModel.emitStateFlow()
viewModel.someStateFlow.first() shouldBe expected

// shared flow
launch {
    viewModel.emitSharedFlow()
}
viewModel.someSharedFlow.first() shouldBe expected

작성 사유(= 푸념)

새 프로젝트에서 LiveData의 대체제로 Flow를 쓰는데 (사유: Clean Architecture) 테스트 하기 까다롭다고 느꼈다.

기존 LiveData는 테스트 시 바로바로 값을 가져올 수 없어 구글에서 getOrAwaitValue라는 Work Around를 제공했다.

fun <T> LiveData<T>.getOrAwaitValue(
    time: Long = 2,
    timeUnit: TimeUnit = TimeUnit.SECONDS,
    afterObserve: () -> Unit = {}
): T {
    var data: T? = null
    val latch = CountDownLatch(1)
    val observer = object : Observer<T> {
        override fun onChanged(o: T?) {
            data = o
            latch.countDown()
            this@getOrAwaitValue.removeObserver(this)
        }
    }
    this.observeForever(observer)

    try {
        afterObserve.invoke()

        // Don't wait indefinitely if the LiveData is not set.
        if (!latch.await(time, timeUnit)) {
            this.removeObserver(observer)
            throw TimeoutException("LiveData value was never set.")
        }
    } finally {
        this.removeObserver(observer)
    }
    @Suppress("UNCHECKED_CAST")
    return data as T
}

저거 그대로 쓰고 싶은데 Flow에 asLiveData 먹여도 안 된다. ㅠㅠ

https://github.com/cashapp/turbine

 

GitHub - cashapp/turbine: A small testing library for kotlinx.coroutines Flow

A small testing library for kotlinx.coroutines Flow - GitHub - cashapp/turbine: A small testing library for kotlinx.coroutines Flow

github.com

Flow 테스트 하는 법 검색하면 자꾸 Turbine이 나오는데... 나는 좀 의심스럽다... 첨 들어본 회사고, 버전 0.7.0에 멈춰있고, Star에 비해 Watch, Fork도 적은 것 같고... 문제 생기면 내가 책임지고 고쳐야 한다...

암튼 원리? 일걸요..

  • first() 사용하면 suspend 되고 값 생기면 suspend 풀린다.
  • StateFlow는 결과값을 유지하기 때문에 위처럼 정직하게 실행해도 shouldBe 이하 구문이 실행된다.
  • SharedFlow는 replay 설정되지 않은 이상 결과값 유지하지 않는다.
    • 정직하게 실행하면 emit -> first()... 값이 없네? 기달. -> 무한 대기
    • 코루틴을 이용하여 기달 -> emit 순서로 실행되도록 만든다. 불안하면 delay를 줘도 됨.
  • 맞으면서 배웠음. 정확한 원리 모름...

 

Project Level Config | Kotest

Kotest is flexible and has many ways to configure tests, such as configuring the order of tests inside a spec, or how

kotest.io

 

반응형