[Android] Mockito는 언제 활용하는게 좋을까요?

윤호이·2023년 11월 5일
0

Test

목록 보기
5/13
post-thumbnail

서론

지금 까지 테스트 관련 포스트를 다뤄오면서
mock 객체 사용을 지양하자고 계속 해서 다뤄왔습니다.

하지만! 그럼에도 불구하고 mock 객체를 활용해야하는 순간이 있습니다.

함께 보시죠.

Mock 객체가 필요한 순간

바로 다른 모듈에 대한 정보가 없을 때 입니다.

무슨 상황이냐고요?

클린 아키텍처를 살펴봅시다.

presentation과 data는 최소한 인터페이스가 아닌 클래스들을 가지고 있겠지만

domain은 최소한의 클래스와 인터페이스로 구성된 Layer입니다.

domain은 추상화된 인터페이스를 가지고 있고 구현체는
data에서 관리합니다.

domain은 data에 대한 구체적인 정보가 없고 오로지 자기 자신밖에 모릅니다.

그럼 domain은 어떻게 테스트 할까요?
구체적인 구현체도 없고 오로지 Interface랑 모델 및 기타 클래스 밖에없는데...

이때 주로 Mockito를 사용합니다.

Mockito 의존성 설정

testImplementation ("io.mockk:mockk:1.12.0")
androidTestImplementation ("io.mockk:mockk-android:1.12.0")

의존성을 App Gradle에 추가해줍시다.

Mock객체 생성

테스트할 Usecase

class AddNumbersUseCase @Inject constructor(private val calculator: Calculator) {
    operator fun invoke(a: Int, b: Int) = calculator.add(a, b)
}

calculator는 domain layer라 구현정보는 없는 인터페이스입니다.

class MockCalculatorTest {

	//1. Mocking 할 객체에 어노테이션 추가
    @MockK
    lateinit var usecase: AddNumbersUseCase

	//2. 어노테이션 초기화
    @Before
    fun setUp() {
        MockKAnnotations.init(this)
    }

    @Test
    fun `숫자를_더한다`() {
        //Given
        val a = 1
        val b = 2

        //3. When
        //Mock 객체 사용전 행동 지정
        every { usecase.invoke(a, b) } returns 3
        val result = usecase.invoke(a, b)

        //Then
        assertEquals(3, result)
    }
}

1 ~ 3번 과정을 통해 Mock 객체가 사용 가능해집니다.

Mock 행동 지정법

every { usecase.invoke(a, b) } returns 3
모든 usecase.invoke(1, 2) 는 3을 반환합니다.

사용법 굉장히 간단하죠?

테스트를 실행하니 정상 동작합니다.

하고 싶은 말

되도록이면 실제 객체를 통해 테스트하고
불가피 하다면 그때 Mockito를 사용 하는 것이 맞다고 생각합니다.
Mockito는 실제 객체의 행동을 흉내낼 뿐 실제 객체가 아닙니다.
테스트를 했을 때 테스트는 통과하지만 실제로는 동작 실패하는 경우가 생길 수도 있습니다.

다른 모듈에 의존성을 가지지 않고 주로 인터페이스로 이루어진
domain같은 모듈에만 사용하는게 좋겠죠?

최대한 실제객체로 테스트 합시다!

profile
열정은 내 삶의 방식, 꾸준함은 내 삶의 증명

0개의 댓글