On this page
Kotlin classes are final by default, suspend functions take hidden continuation parameters, and top-level functions and objects aren't ordinary Java classes. Early Mockito struggled with all of that, which is why MockK became popular in Android. Both libraries have matured, so the choice is now mostly about style.
The same test in both
@Test
fun `refresh shows error when repository fails`() = runTest {
val repo = mockk<ArticleRepository>()
coEvery { repo.refresh() } throws IOException()
every { repo.observeArticles() } returns flowOf(emptyList())
val vm = ArticlesViewModel(repo)
vm.refresh(); advanceUntilIdle()
assertEquals("Couldn't refresh", vm.uiState.value.message)
coVerify(exactly = 1) { repo.refresh() }
}@Test
fun `refresh shows error when repository fails`() = runTest {
val repo = mock<ArticleRepository> {
onBlocking { refresh() } doThrow IOException() // doThrow works with checked exceptions too
on { observeArticles() } doReturn flowOf(emptyList())
}
val vm = ArticlesViewModel(repo)
vm.refresh(); advanceUntilIdle()
assertEquals("Couldn't refresh", vm.uiState.value.message)
verifyBlocking(repo, times(1)) { refresh() }
}Comparison
| Aspect | MockK | Mockito (+ mockito-kotlin) |
|---|---|---|
| Kotlin-first API | Yes (every, coEvery, DSL) | Via mockito-kotlin extensions |
| Final classes | Supported | Supported (inline mock maker is the default in recent versions) |
| Suspend functions | coEvery / coVerify | onBlocking / verifyBlocking |
| Objects, top-level and extension functions, constructors | mockkObject, mockkStatic, mockkConstructor | Limited (static mocking via mockStatic) |
| Relaxed mocks | mockk(relaxed = true) | Default answers (null/zero), RETURNS_DEEP_STUBS |
| Speed | Can be slower to initialise | Generally fast |
| Ecosystem familiarity | Very common in Kotlin Android projects | Universal in Java and Android |
Often better: fakes
class FakeArticleRepository : ArticleRepository {
val articles = MutableStateFlow<List<Article>>(emptyList())
var failRefresh = false
override fun observeArticles(): Flow<List<Article>> = articles
override suspend fun refresh() { if (failRefresh) throw IOException() }
}When mocks are the right tool
- Verifying a side effect happened exactly once (analytics event, logger call).
- Third-party classes that are hard to fake and that you don't wrap.
- Simulating rare failures in deep collaborators.
Team recommendations
Kotlin-only Android app
MockK for its Kotlin-native API, with fakes for repositories.
Mixed Java/Kotlin codebase
Mockito with mockito-kotlin keeps one library for both languages.
Large test suites
Prefer fakes. Measure mock initialisation cost if tests feel slow.
Common mistakes
- Mocking data classes and value types. Just create real instances.
- Relaxed mocks everywhere, which hide missing stubs and let tests pass vacuously.
- Verifying every call, which breaks tests on harmless refactors.
- Mocking the class under test.
Frequently asked questions
Can I use both in one project?
You can, but pick one as the standard to keep tests consistent.
Do I need special setup for final classes with Mockito?
Recent Mockito versions use the inline mock maker by default, which supports final classes. Older setups needed explicit configuration.
What about mocking Android framework classes?
Avoid it. Wrap framework calls behind your own interfaces, or use Robolectric when you need real behaviour.
Conclusion
MockK offers the most Kotlin-native API, and Mockito with mockito-kotlin is equally capable for most needs. For your own repositories and data sources, fakes usually produce clearer, more robust tests than either.
Next step: find a different kind of bug in Android Memory Leaks: Causes and Solutions.
Official references
๐ฑ Apps built by Yunok Tech
Real Android apps on Google Play, free to download.
Walzi4K wallpapers for lock and home screenGet it โธ
NotiVaultNotification history: recover dismissed notificationsGet it โธ
Ready to build real Android applications?
Kotlin fluency makes everything else in Android easier, from coroutines and Flow to Compose and clean architecture. The fastest way to build that fluency is to write real Kotlin every day and get feedback on it.
Move beyond theory and strengthen your Android development skills with Yunoktech's Android course. Learn core concepts, practical implementation, modern Android development techniques, and the reasoning behind building maintainable applications.
Explore the Android course and take your next step as an Android developer.