Mockito

Mockito는 객체를 Mocking하는데 사용되는 Java 기반의 라이브러이다. JUnit과 함께 Unit Test를 작성하는데 사용된다. Android도 Unit Test를 작성하는데 공식적으로 Mockito를 사용하도록 권장하고 있다.

이전에 Test와 관련된 글에서도 살펴봤듯이 Android는 JVM에서 동작하는 Test와 디바이스 또는 애뮬레이터에서 동작하는 Instrumentation Test가 있다.

mocking : 쉽게 말해서 흉내낸다는 것을 의미한다.

이번에는 Mockito를 이용해서 Unit Test를 작성하는 방법에 대해서 알아보려고 한다.

Gradle

자바를 사용한다면 다음과 같이 한 줄을 app/build.gralde 파일에 추가하면 된다.

1
testImplementation 'org.mockito:mockito-core:2.24.5'

아래의 줄은 안드로이드 Test를 위해 mockito를 사용할 때, 필요한 의존성이다. 추가하지 않아도 테스트 코드로 검증할 때 필요하지 않기 때문에 필요시 추가하도록 하자!

아래는 androidTest 파일에서 mockito를 사용할 때, 필요하다.

1
androidTestImplementation("org.mockito:mockito-android:2.24.5")

하지만 코틀린을 사용한다면, 이렇게 의존성을 추가하여 사용할 경우에 다음과 같은 문제가 발생한다.

Mockito cannot mock/spy final class라는 에러가 발생한다.

에러 로그를 확인해보면, Mockito가 final class를 Mock으로 만들려고 했기 때문이다. Kotlin은 기본적으로 final class로 설정되기 때문에 이러한 문제가 발생한 것이다.

해결하기 위해서 open 키워드를 Mock으로 만들려는 클래스 앞에 붙여주면 에러가 발생하지 않는다. 그러나 이런 작업을 매번 해주는 것은 귀찮은 작업이다. 그러나 우리에겐 라이브러리가 있다. 행복한 일이다~ ^__^

아래의 줄을 app/build.gradle 파일에 추가하면 된다.

1
testImplementation 'org.mockito:mockito-inline:2.13.0'

간단히 Person이라는 클래스를 만들어서 Mockito를 사용해 mock 객체를 만들고 Mockito에서 제공하는 함수를 이용해서 person 객체의 반환 값을 지정해주는 예제이다.

1
2
3
4
data class Person(
val name: String
val age: Int
)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import org.mockito.Mockito.*

class PersonTest{
@Test
fun personMockTest(){
val p: Person = mock(Person::class.java)
assertTrue(p != null)


`when`(p.name).thenReturn("VictoryWoo")
`when`(p.age).thenReturn(27)


assertTrue("VictoryWoo" == p.name)
assertTrue(27 == p.age)
}
}
  • mock을 통해서 Person 클래스의 객체를 생성한다.
  • when() 함수를 통해서 p 객체의 name, age의 반환값을 정해준다.
  • 마지막으로 p의 반환값이 기대하는 값과 같은지 비교한다.
  • 성공적으로 2개의 테스트를 통과할 수 있다.
  • 여기서 org.mockito.Mockito.*를 import하였기 때문에 Mockito.을 생략해서 쓸 수 있다.

이처럼 객체의 반환값을 임의로 정해 Unit Test를 할 수 있는 단순한 기능 외에도 Mockito는 객체에 데이터를 추가하는 다양한 기능 및 검증을 할 수 있는 함수를 많이 제공한다.

이번에는 Mockito와 관련된 기본 개념들에 대해서 살펴봤다.
다음에는 조금 더 심화된 내용과 Mockito를 Kotlin과 함께 사용할 때, 모호한 구문을 어떻게 해결할 수 있는지에 대해서 알아볼 예정이다.

참고