원래 자바 환경에서는 객체를 모킹해서 테스트할 때 mockito를 썼는데 GPT에 물어보니 MockK를 추천해주길래 어떤 차이가 있는지 알아봤다.
Kotlin 전용으로 나온 라이브러리가 MockK다.
Mockito VS MockK
항목 | Mockito | MockK |
언어 지원 | 주로 Java용으로 설계됨 | 주로 Kotlin을 위해 설계됨 |
코틀린 지원 | Kotlin 지원이 제한적이며, 일부 기능에 제약이 있음 | Kotlin에서 자연스럽게 동작하며 코틀린의 특징을 잘 지원 |
Mock 방식 | 클래스 기반 모킹, Kotlin의 final class 모킹에 추가 설정 필요 | 클래스와 객체 모두 모킹 가능 (Kotlin 친화적) |
확장 함수 지원 | 확장 함수 모킹 불가 | 확장 함수 모킹 가능 |
객체 모킹 | 객체(Object) 모킹 불가 | 객체(Object) 모킹 가능 |
동시성 지원 | 동시성 관련 테스트 지원에 일부 제약이 있음 | 동시성 관련 기능에 대한 테스트 지원이 비교적 강력함 |
DSL 스타일 | Java에 맞춘 스타일로 Kotlin 코드에서 약간 불편함 | Kotlin DSL을 사용해 코드가 더 직관적이고 깔끔함 |
검증 구문 | ** verify **와 같은 구문 사용 | verify , every , just 등 다양한 구문 사용 |
안정성 | 오래된 라이브러리로 안정적 | 새롭게 등장한 라이브러리로 Kotlin에 더 최적화 됨 |
1. 언어 지원
- Mockito는 Java 환경에서 널리 사용되며, 기본적으로 Kotlin에서 사용할 수 있지만, Kotlin의 특성에 맞지 않는 부분이 있습니다. 특히 Kotlin의
final
클래스와 메서드는 Mockito에서 기본적으로 모킹할 수 없습니다.
- MockK는 Kotlin을 위해 설계된 모킹 라이브러리로, Kotlin의 특수한 기능들을 자연스럽게 지원합니다. 예를 들어, Kotlin의
final
클래스, 확장 함수 등을 쉽게 모킹할 수 있습니다.
2. 코틀린의 final class
모킹
- Mockito에서는 Kotlin의
final class
와 메서드를 모킹하려면 추가 설정이 필요합니다. 이를 위해mock-maker-inline
설정을 추가해야 합니다.
# src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker mock-maker-inline
MockK는 기본적으로 Kotlin의
final class
나 확장 함수를 모킹할 수 있도록 지원하므로, 별도의 추가 설정이 필요 없습니다.3. 확장 함수 모킹
- Mockito는 Kotlin의 확장 함수를 모킹할 수 없습니다.
- MockK는 확장 함수를 자연스럽게 모킹할 수 있습니다.
MockK 확장 함수 모킹 예시:
fun String.customExtension(): String { return this + " extended" } @Test fun `test extension function`() { mockk<String>() every { "test".customExtension() } returns "mocked" assertEquals("mocked", "test".customExtension()) }
4. 객체(Object) 모킹
- Mockito는 Kotlin의
object
객체(싱글톤 패턴)에 대한 모킹을 지원하지 않습니다.
- MockK는 Kotlin의
object
객체도 모킹할 수 있습니다.
object Singleton { fun sayHello(): String = "Hello" } @Test fun `test singleton object`() { mockkObject(Singleton) every { Singleton.sayHello() } returns "Mocked Hello" assertEquals("Mocked Hello", Singleton.sayHello()) }
5. 구문 스타일 및 가독성
- Mockito는 Java 스타일의 구문을 사용하며, Kotlin 코드에서 약간 부자연스러울 수 있습니다.
Mockito 구문 예시:
val mockedList = mock(List::class.java) `when`(mockedList.size).thenReturn(3)
- MockK는 Kotlin DSL 스타일을 사용하여 코드가 더 자연스럽고 가독성이 좋습니다.
MockK 구문 예시:
val mockedList = mockk<List<String>>() every { mockedList.size } returns 3
6. 검증 구문
- Mockito는 주로 **
verify
*를 사용하여 메서드 호출을 검증합니다.
verify(mockedList).add("item")
- MockK는
verify
,every
,just
등의 구문을 지원하며, 다양한 검증 옵션을 제공합니다.
verify { mockedList.add("item") }
7. 성능 및 동시성
- Mockito는 오래된 라이브러리로 안정적이지만, 동시성 관련 테스트에서는 일부 제약이 있을 수 있습니다.
- MockK는 비교적 새로운 라이브러리로 동시성 문제에 대한 테스트에서 강력한 기능을 제공합니다.
결론
- Mockito는 Java에서 오랫동안 사용되어 온 안정적인 라이브러리지만, Kotlin과의 호환성에는 일부 한계가 있습니다.
- MockK는 Kotlin에 특화된 모킹 라이브러리로, Kotlin의
final class
, 확장 함수, 객체 모킹 등 Kotlin의 특수한 기능을 자연스럽게 지원합니다. DSL 스타일의 구문도 Kotlin 개발자에게 더 익숙하고 가독성이 좋습니다.
Kotlin 프로젝트에서는 MockK를 사용하는 것이 더 적합하고 편리할 가능성이 큽니다. 그러나 Java 프로젝트나 Java/Kotlin 혼합 프로젝트에서는 여전히 Mockito를 사용할 수 있습니다.