이전의 Mockito을 이용한 Unit Test 글에 이어 이번에는 좀 더 Mockito을 활용하는 방법을 알아보겠습니다.
1. 먼저 앱 모듈의 build.gradle 파일에 Mockito 의존성을 추가합니다.
testImplementation("org.mockito:mockito-core:4.0.0")
testImplementation("org.mockito:mockito-inline:2.21.0")
testImplementation("com.nhaarman.mockitokotlin2:mockito-kotlin:2.2.0")
org.mockito:mockito-inline 라이브러리는 Final 클래스와 Spy 클래스(Mockito Kotlin 라이브러리를 사용할 때)를 모킹하기 위한 것이 주요 목적입니다. 파이널 클래스는 상속될 수 없고, 스파이 클래스는 Mockito Kotlin을 사용할 때 스파이화할 수 없는 클래스를 나타냅니다. 이러한 제약을 극복하고 모의 객체 또는 스파이 객체를 생성하기 위해 mockito-inline 라이브러리를 사용할 수 있습니다.
파이널 클래스 및 스파이 클래스를 모킹할 때 mockito-inline 라이브러리를 사용하면 Mockito가 내부적으로 ASM(Java 바이트 코드 조작 라이브러리)를 사용하여 모킹을 가능하게 합니다. 이를 통해 Mockito는 파이널 클래스와 스파이 클래스를 모킹하고 모의 객체를 생성할 수 있게 됩니다. 따라서 파이널 클래스나 스파이 클래스를 모킹해야 하는 경우 mockito-inline 라이브러리를 사용하여 Mockito의 능력을 확장할 수 있습니다.
따라서 파이널 클래스나 스파이 클래스를 모킹해야 하는 경우 mockito-inline 라이브러리를 사용하여 Mockito의 능력을 확장할 수 있습니다.
com.nhaarman.mockitokotlin2 라이브러리는 Mockito와 함께 Kotlin 언어에서 모의 객체를 생성하고 사용하는 데 도움을 주는 라이브러리입니다. 이 라이브러리를 사용하는 주요 이유와 장점은 다음과 같습니다:
- Kotlin과의 호환성: Kotlin은 Java와는 다른 언어이며, Mockito는 Java에 더 적합한 라이브러리입니다. Kotlin에서 기본 Mockito를 사용할 때 몇 가지 문법적 차이점과 제약 사항이 발생할 수 있습니다. com.nhaarman.mockitokotlin2 라이브러리는 Kotlin에서 Mockito를 더 편리하게 사용할 수 있도록 설계되었습니다. 따라서 Kotlin에서 Mockito를 사용하는 데 생기는 어려움을 줄일 수 있습니다.
- 더 간결한 문법: **com.nhaarman.mockitokotlin2**를 사용하면 Kotlin의 간결한 문법을 활용하여 모의 객체를 생성하고 설정할 수 있습니다. Kotlin의 확장 함수와 람다 표현식을 사용하여 테스트 코드를 더 읽기 쉽고 간결하게 작성할 수 있습니다.
- 코드 가독성 향상: Kotlin과 **com.nhaarman.mockitokotlin2**를 함께 사용하면 테스트 코드의 가독성이 향상됩니다. 예를 들어, Mockito를 사용하여 모의 객체를 생성하고 설정하는 코드가 더 간결하고 직관적으로 표현됩니다.
예를 들어, 기본 Mockito를 사용한 Java 코드:
javaCopy code
when(mockedList.add(anyString())).thenReturn(false);
**com.nhaarman.mockitokotlin2**를 사용한 Kotlin 코드:
kotlinCopy code
whenever(mockedList.add(any<String>())).thenReturn(false)
이처럼 Kotlin과 **com.nhaarman.mockitokotlin2**를 함께 사용하면 테스트 코드를 작성하기 더 쉽고 가독성 있게 만들 수 있습니다.
2. 테스트 코드를 작성합니다.
import androidx.arch.core.executor.testing.InstantTaskExecutorRule
import com.nhaarman.mockitokotlin2.whenever
import com.swjsw.app.cleanflashlight.common.util.FlashLightManager
import com.swjsw.app.cleanflashlight.flashlight.FlashlightViewModel
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay
import kotlinx.coroutines.test.UnconfinedTestDispatcher
import kotlinx.coroutines.test.resetMain
import kotlinx.coroutines.test.runTest
import kotlinx.coroutines.test.setMain
import org.junit.Assert.assertEquals
import org.junit.Before
import org.junit.Rule
import org.junit.Test
import org.mockito.Mock
import org.mockito.MockitoAnnotations
class FlashlightViewModelUnitTest {
@get:Rule
val rule = InstantTaskExecutorRule()
@Mock
lateinit var flashlightManager: FlashLightManager
private lateinit var viewModel: FlashlightViewModel
private lateinit var flashlightManagerListener: FlashlightViewModel.FlashlightViewModelListener
@Before
fun setup() {
MockitoAnnotations.openMocks(this)
viewModel = FlashlightViewModel()
flashlightManagerListener = FlashlightViewModel.FlashlightViewModelListener(viewModel)
whenever(flashlightManager.flashlightOn()).thenAnswer {
flashlightManagerListener.onFlashLightOn()
}
whenever(flashlightManager.flashlightOff()).thenAnswer {
flashlightManagerListener.onFlashLightOff()
}
whenever(flashlightManager.flashlightToggle()).thenAnswer {
if (viewModel.isFlashlightOn.value == true) {
flashlightManagerListener.onFlashLightOff()
} else {
flashlightManagerListener.onFlashLightOn()
}
}
viewModel.setFlashlightManger(flashlightManager)
viewModel.setFlashlightMangerListener(flashlightManagerListener)
}
@Test
fun testTurnOnFlashlight() {
viewModel.turnOnFlashlight()
assertEquals(true, viewModel.isFlashlightOn.getOrAwaitValue())
}
@Test
fun testTurnOffFlashlight() {
viewModel.turnOffFlashlight()
assertEquals(false, viewModel.isFlashlightOn.getOrAwaitValue())
}
}
위 테스트 코드에서 FlashLightManager를 모킹하고 ‘whenever’ 를 사용해서 스터빙을 하고 있습니다.
“@Mock” 애노테이션과 “MockitoAnnotations.openMocks(this)” 을 이용해서 Mock 객체를 만드는 것을 볼 수 있습니다.
'Android > Unit Test' 카테고리의 다른 글
모킹(Mocking)과 스터빙(Stubbing) (0) | 2023.09.27 |
---|---|
[Android] Unit Test 작성하기 -4(Mockito-1) (0) | 2023.09.27 |
[Android] 구글 Coroutine Test 정리 글 (0) | 2023.09.22 |
[Android] Unit Test 작성하기 -3 (0) | 2023.09.22 |
[Android] Unit Test 작성하기 -2 (0) | 2023.09.22 |