How does MockK let you create and verify mocks in Kotlin, and why is it preferred over Mockito for Kotlin code?
answer
- mockk() + every { } returns + verify { }
- coEvery / coVerify for suspend functions
- relaxed = true auto-returns defaults
- slot + capture for argument capture
- MockK mocks final classes; Mockito needs inline plugin
basics
~20 sMockK is a Kotlin mocking library. You create a fake object with mockk(), tell it what to return using every { ... } returns ..., call your code, then check the fake was used with verify { ... }.
solid answer
~40 sMockK is a Kotlin-first mocking framework. `mockk<T>()` creates a strict mock; `every { mock.foo() } returns x` stubs behavior, and `verify { mock.foo() }` checks interactions. It understands Kotlin idioms natively: it mocks `final` classes (Kotlin classes are final by default) without bytecode tricks, mocks `suspend` functions via `coEvery`/`coVerify`, supports `relaxed = true` mocks that auto-return sensible defaults, and provides `slot`/`capture` for argument capturing. It can mock top-level and extension functions with `mockkStatic`, and objects with `mockkObject`. Mockito needs `mockito-inline` plus a Kotlin plugin to touch final classes and still struggles with suspend functions and extension functions, which is why MockK is the Kotlin default. Always pair `mockk` setup with `confirmVerified` or `verify(exactly = ...)` to catch unexpected calls.
code
kotlin · 19 linesimport io.mockk.*
import kotlin.test.Test
import kotlin.test.assertEquals
class UserServiceTest {
@Test
fun `greets known user`() {
val repo = mockk<UserRepository>()
val slot = slot<Long>()
every { repo.findById(capture(slot)) } returns User(7, "Sam")
val result = UserService(repo).greet(7)
assertEquals("Hello, Sam", result)
assertEquals(7L, slot.captured)
verify(exactly = 1) { repo.findById(7) }
confirmVerified(repo)
}
}go deeper
Can create a mockk, stub with every { } returns, and verify a call happened.
Uses coEvery/coVerify for suspend, slot/capture for arguments, and knows relaxed vs strict trade-offs.
Explains why MockK beats Mockito for Kotlin (final classes, suspend, extensions) and enforces confirmVerified discipline.
Sets team policy on mock strictness, when to prefer fakes over mocks, and avoiding over-mocking brittle tests.
## What MockK Is MockK is a mocking library built **for Kotlin**. A *mock* is a stand-in object whose behavior you script and whose interactions you can verify, used to isolate the unit under test from collaborators (databases, services). ## Test-Double Vocabulary - **Stub**: returns canned answers (`every { ... } returns ...`). - **Mock**: a stub you also *verify* was called. - **Spy**: wraps a real object, overriding some calls (`spyk(realObject)`). - **Relaxed mock**: `mockk(relaxed = true)` auto-returns defaults (0, "", empty) for unstubbed calls instead of throwing. ## Core API ```kotlin val repo = mockk<UserRepository>() every { repo.findById(1) } returns User(1, "Ann") val service = UserService(repo) val user = service.greet(1) verify(exactly = 1) { repo.findById(1) } confirmVerified(repo) // no other interactions happened ``` ## Kotlin-Native Capabilities - **Final classes**: Kotlin classes are `final` by default; MockK mocks them out of the box. - **Suspend functions**: stub with `coEvery`, verify with `coVerify` — essential for coroutine code. - **Argument capture**: `val s = slot<User>(); every { repo.save(capture(s)) } just Runs; ... s.captured`. - **`just Runs`** / `returnsMany` / `answers { ... }` for void/dynamic responses. - **Statics & objects**: `mockkStatic("...Kt")` for top-level/extension functions, `mockkObject(MyObject)` for `object` singletons. ## MockK vs Mockito Mockito assumes Java semantics: it cannot mock `final` classes without `mockito-inline`, has no native `suspend` support, and cannot mock Kotlin extension/top-level functions. MockK handles all of these natively, so it is the de-facto standard for Kotlin. ## Discipline Use strict mocks (the default) plus `verify(exactly = ...)` and `confirmVerified` so unexpected collaborator calls fail the test rather than passing silently.
- How do you mock a suspend function with MockK?Use coEvery { mock.fetch() } returns value to stub it and coVerify { mock.fetch() } to verify. The plain every/verify don't run inside a coroutine context for suspend calls.
- What does a relaxed mock change, and what's the risk?mockk(relaxed = true) auto-returns defaults for unstubbed calls instead of throwing. The risk is hiding missing stubs, so tests pass on behavior you never intended; prefer strict mocks or relaxUnitFun = true.
A mock is a stunt double: you choreograph its moves (every) and afterward review the footage to confirm it did them (verify).
saying these in an interview costs you the question
- Using every/verify (not coEvery/coVerify) for suspend functions
- Defaulting every mock to relaxed = true to silence errors
- Never calling confirmVerified, so extra interactions go unnoticed
- Claiming Mockito handles Kotlin final classes with no extra config
- Confusing a spy (spyk) with a full mock