본문 바로가기

ANDROID/Testing

[Android/Testing] Hot StateFlow의 유닛 테스팅 in ViewModel

이제 LiveData의 시대가 가고 자연스레 Flow의 시대가 도래한 듯 하다. LiveData와 마찬가지로 동적인 속성을 가진 Flow의 테스팅을 위해서는 일련의 설정이 필요한데, 해당 포스트에서는 다루는 빈도가 많을 Hot StateFlow의 Unit-Test 설정 및 방식을 정리하려 한다.

 

Dependencies

org.jetbrains.kotlinx:kotlinx-coroutines-test:1.7.3
org.jetbrains.kotlinx:kotlinx-coroutinesandroid:1.7.3

kotlin = "1.8.10"

Testing

1. Before, After Annotation으로 테스트 전후 Dispatcher를 UnconfinedTestDispatcher로, 테스트 이후 이를 초기화 한다. 초기화 과정의 경우 테스트를 위해 사용된 DI의 초기화에 사용되므로, 다수의 테스트 케이스를 수행하고 DI를 쓰고 있다면 꼭 선언해주어야 하겠다.

@Before
fun setup() {
    Dispatchers.setMain(UnconfinedTestDispatcher())
}

@After
fun teardown() {
    Dispatchers.resetMain()
}

2. 테스트 케이스를 runTest로 감싸고, 환경 설정을 arrange한다. 

@Test
fun testLazilySharingViewModel() = runTest {
    val fakeRepository = HotFakeRepository()
    val viewModel = MyViewModelWithStateIn(fakeRepository)
}

3. StateFlow가 값을 수신할 수 있도록 backgroundScope에서 대상 StateFlow를 collect해준다. 이 과정이 없다면 StateFlow는 연결된 Flow가 방출하는 데이터를 전달 받지 않으므로 테스트가 불가능하다.

@Test
fun testLazilySharingViewModel() = runTest {
    val fakeRepository = HotFakeRepository()
    val viewModel = MyViewModelWithStateIn(fakeRepository)

    backgroundScope.launch(UnconfinedTestDispatcher(testScheduler)) {
        viewModel.score.collect()
    }
}

4. 다음 대상 StateFlow가 값을 전달받는 로직을 수행하고, 이후 기대하는 값으로 StateFlow가 업데이트 되었는지 확인한다.

@Test
fun testLazilySharingViewModel() = runTest {
    val fakeRepository = HotFakeRepository()
    val viewModel = MyViewModelWithStateIn(fakeRepository)

    // Create an empty collector for the StateFlow
    backgroundScope.launch(UnconfinedTestDispatcher(testScheduler)) {
        viewModel.score.collect()
    }

    assertEquals(0, viewModel.score.value) // Can assert initial value

    // Trigger-assert like before
    fakeRepository.emit(1)
    assertEquals(1, viewModel.score.value)

    fakeRepository.emit(2)
    fakeRepository.emit(3)
    assertEquals(3, viewModel.score.value)
}

 

 

< Reference >

 

Android에서 Kotlin 흐름 테스트  |  Android Developers

Android에서 Kotlin 흐름 테스트 컬렉션을 사용해 정리하기 내 환경설정을 기준으로 콘텐츠를 저장하고 분류하세요. 흐름과 통신하는 단위나 모듈을 테스트하는 방법은 테스트 대상이 흐름을 입력

developer.android.com