이제 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 > Testing' 카테고리의 다른 글
[Testing/Unit-test] Context를 포함하는 ViewModel의 Unit Test (0) | 2022.01.14 |
---|---|
[Kotlin/UnitTesting] LiveData Mocking하기 (0) | 2022.01.06 |
[안드로이드] 람다 Function을 파라미터로 가지는 로직의 Unit Testing! (0) | 2021.01.11 |
[안드로이드/Firebase] adb를 Android studio 터미널에 설정하기, adb 이용해 Firebase event 디버깅하기 (0) | 2020.12.14 |
[Jacoco] Jacoco와 gradle로 프로젝트 코드 커버리지 확인하기(Gradle 3.6 버전 이상의 경우) (0) | 2020.03.23 |