Unit testing is a crucial part of any software development process, especially in Kotlin-based Android or backend projects. One of the most popular libraries for mocking in Kotlin is MockK. Unlike other Java-based mocking frameworks, MockK is designed specifically for Kotlin, supporting features like extension functions, coroutines, and final classes out of the box.

In this article, we’ll explore how to use MockK for unit testing in Kotlin, why it’s preferred by Kotlin developers, and some of the best practices you should follow.
What is MockK?
MockK is a modern mocking framework tailored for Kotlin. It allows developers to create mock objects, spy behavior, and verify interactions with ease. MockK supports a wide range of Kotlin features, such as:
- Mocking final classes and methods
- Mocking extension functions
- Working seamlessly with coroutines and suspend functions
- Creating relaxed mocks (to avoid writing boilerplate return values)
- Verifying function calls and argument values
This makes MockK a preferred choice over traditional mocking libraries like Mockito when working in a Kotlin project.
Basic Setup
To start using MockK in your project, add the following dependencies to your build.gradle.kts
:
testImplementation("io.mockk:mockk:1.13.7") testImplementation("org.jetbrains.kotlinx:kotlinx-coroutines-test:1.7.1") testImplementation("junit:junit:4.13.2")
This setup enables you to test regular and coroutine-based functions using JUnit.
Creating a Simple Mock
Suppose you have a class UserRepository
with a method getUserById(id: Int)
that fetches a user. In your UserViewModel
, you want to test logic that uses this repository.
class UserRepository { fun getUserById(id: Int): User { return User(id, "John Doe") } }
In your test, you can mock UserRepository
like this:
class UserViewModelTest { private val repository = mockk<UserRepository>() private lateinit var viewModel: UserViewModel @Before fun setup() { viewModel = UserViewModel(repository) } @Test fun `test user is fetched correctly`() { every { repository.getUserById(1) } returns User(1, "John Doe") val result = viewModel.getUserName(1) assertEquals("John Doe", result) verify { repository.getUserById(1) } } }
Mocking Suspend Functions and Coroutines
For suspend functions, you must use coEvery
and coVerify
:
@Test fun `test suspend function fetches user`() = runTest { coEvery { repository.getUserById(2) } returns User(2, "Jane") val result = viewModel.getUserNameSuspend(2) assertEquals("Jane", result) coVerify { repository.getUserById(2) } }
MockK also supports relaxed = true
mocks which allow skipping explicit return values:
val relaxedRepo = mockk<UserRepository>(relaxed = true)
Best Practices Using MockK
- Use
clearMocks()
orunmockkAll()
in@After
to clean up mocks. - Prefer
relaxed = true
only for quick prototyping; avoid it for strict test behavior. - Use
slot
orcapture
to track argument values passed into mocked methods. - Use
excludeRecords {}
to ignore internal interactions during verification.
Why MockK over Mockito?
MockK was built specifically for Kotlin, whereas Mockito still relies on Java-based bytecode generation. This leads to better support for Kotlin-specific features. Moreover, MockK offers concise syntax, improved coroutine handling, and a more Kotlin-idiomatic API.
For a deeper comparison of mocking tools in Kotlin, you can explore this external guide on Kotlin mocking frameworks.
Conclusion
MockK is a powerful and flexible tool that simplifies mocking in Kotlin projects. Its native support for Kotlin syntax, coroutine testing, and concise API makes it a must-have for Kotlin developers focused on clean and effective unit tests. Whether you’re testing a ViewModel, use case, or a repository, MockK offers the tools you need to keep your test suite reliable and maintainable.