

코드를 짜다 보면 테스트 환경이 크게 두 가지로 나뉜다.
Local Unit Test (test/)
JVM 환경에서 돌아간다. 안드로이드 폰도, 에뮬레이터도 필요없다.
Instrumentation Test (androidTest/)
진짜 안드로이드 기기나 에뮬레이터에서 돌아간다.
Instrumentation Test 는 진짜 무대 공연
조명, 음향, 무대 세트(=Android OS) 가 다 준비되어 있다.
공연에 필요한 모든 장치도 구비되어있다.
Local Unit Test 는 리허설장
배우(=ViewModel, Repository) 는 있지만, 무대장치(=AndroidOS) 는 없다.
대본을 읽고, 발음만 맞출 수 있다. 전체 조명이나 음향은 테스트가 불가능하다.
ApplicationProvider.getApplicationContext()
Local Test 에서 ApplicationProvider 를 호출하는 행위는
리허설장(=Unit Test) 환경에서 조명 켜달라는 말하는 것도 다름없다.
ApplicationProvider 는 Android Instrumentation 환경
(즉, connectedAndroidTest)에서만 동작한다.
testDebugUnitTest 처럼 JVM 에서 실행되는 Local Unit Test 에서는
Instrumentation 이 없기 때문에 실행되지 않는다.
리허설에서 진짜 조명을 켤 수 없으니, 가짜 조명을 써야 한다.
Unit Test에서는 안드로이드 프레임워크 객체를 직접 쓰지 않고,
Application을 Mock 을 주입하거나, Test Double로 대체한다.
@Before
fun setup() {
Dispatchers.setMain(testDispatcher)
val context = mockk<Application>(relaxed = true)
viewModel = MyViewModel(context)
}
2. 만약 실제 Context 필요하다면 → Instrumentation Test로 옮기기
ApplicationProvider.getApplicationContext()를 꼭 써야 하는 경우,
androidTest 폴더에서 실행한다.
@RunWith(AndroidJUnit4::class)
class ArtDetailViewModelInstrumentedTest {
private lateinit var viewModel: MyViewModel
@Before
fun setup() {
val context = ApplicationProvider.getApplicationContext<Application>()
viewModel = MyViewModel(context)
}
}