-
Notifications
You must be signed in to change notification settings - Fork 5
Unit Test를 해보자
양성현 edited this page Dec 14, 2022
·
1 revision
우리는 테스트를…
- 리팩터링을 진행하면서 수정이 있을 때마다 테스트해야 했다.
- 기능을 추가할 때마다 버그가 있는지 테스트해야 했다.
에뮬레이터로 실행해서 Log로 확인해야 하는데 이 방법은…
- 테스트 시간이 오래 걸린다.
- 테스트가 일관되지 못한다.
앱의 기능을 늘리거나 리팩터링을 할 때 이러한 테스트 과정은 오랜 시간을 잡아먹었기 때문에
작은 단위로 빠르게 테스트하고자 Unit Test를 사용하게되었습니다.
@RunWith(MockitoJUnitRunner::class)
class PromiseDetailViewModelTest {
@Mock private lateinit var promiseRepository: PromiseRepository
@Mock private lateinit var userRepository: UserRepository
...
뷰모델에 FireStore서버에서 데이터를 불러오기 위한 repository들이 다수 있다.
이러한 repository들은 안드로이드 종속 항목이 있어 Unit Test하는데서 문제가 생기는데
이를 해결할 방법은 Robolectric과 Mock 프레임워크가 있었다.
- Robolectric은 에뮬레이터 기반 Android 테스트와 달리 샌드박스 내에서 실행되어 Android 환경을 원하는 조건으로 구성할 수 있고, 안드로이드 종속 항목을 제공한다.
- Mock 프레임워크는 실제 안드로이드 종속 항목을 사용하지 않고 흉내 내는 가짜 객체를 만들어 테스트를 진행할 수 있게 해준다.
Mock 프레임워크인 Mockito를 사용하게 되어있는데 이유는 외부 요소를 배제하고 테스트하려는 부분에 집중할 수 있다고 생각했다.
@Test
fun getPromise_CorrectMyPromise() = runTest {
`when`(promiseRepository.getPromise(myPromise.promiseId)).thenReturn(
flow {
emit(myPromise)
}
)
`when`(userRepository.getMyInfo()).thenReturn(
flow {
emit(Result.success(myInfo))
}
)
val promise = promiseDetailViewModel.promise.first()
assertEquals(myPromise, promise)
}
Test Double은 앱에서 구성 요소처럼 보이고 작동하지만 특정 동작이나 데이터를 제공하기 위해 테스트에서 생성되는 객체이다. 주요 이점은 테스트를 더 빠르고 간단하게 만든다는 것이다.
Mock은 Test Double의 한 종류이다.
repository들을 Mock 객체로 만들고 테스트 함수에서 어떻게 동작할지 정의해주었다.
외부 요소들을 제외하고 뷰모델 로직만을 테스트할 수 있었다.
- 테스트하기 위해 테스트용 화면을 구현하거나 실제 UI를 구현할 때까지 기다릴 필요가 없어졌다.
- 테스트 속도가 빨라졌다.
- 에뮬레이터에 앱을 설치하고 테스트 케이스를 직접 설정하는 과정이 없이 빠르게 테스트 결과를 확인할 수 있었다.
- 테스트를 일관성 있게 할 수 있다.
- 코드를 수정하지 않으면 작성한 테스트 코드에 따라 같은 결과를 반환한다.
- 테스트하는 데 걸리는 시간이 짧다 보니 기능 구현 및 리팩터링을 진행하면서 적극적으로 테스트를 할 수 있었다.
- 테스트 코드를 작성하면서 테스트할 수 있도록 구조를 변경해야 했고 많은 개선이 이루어졌다.
- 구현 내용이 변경되면 테스트 코드도 개선해야 하지만 이 단점에 비해 테스트 코드를 유지함으로써 얻는 이점이 많았다고 느꼈다.