How do you create a mock with MockK and make one of its methods return a fixed value?
answer
- mockk<T>() = create fake
- every { } returns = script return value
- strict by default: unstubbed call throws
- returnsMany / throws / answers terminators
- reified type param
basics
~10 sCreate the fake object with mockk(), then tell it what to return using every { obj.method() } returns value. After that, calling the method gives back the value you set.
solid answer
~40 sUse the inline function mockk<T>() to create a mock of type T. By default it is a strict mock: every method must be stubbed or the call throws. You define behaviour with every { mock.method(args) } returns result. The lambda after every records which call to stub; returns supplies the canned value. Variants include returnsMany(listOf(...)) for sequential values, throws ex to raise an exception, and answers { ... } for dynamic logic using the call's arguments. Only non-final members are mockable by default; MockK uses bytecode manipulation (and an all-open-style agent) so final Kotlin methods also work via its inline mocking. You typically assign the mock to a val of the interface or class type and inject it into the class under test.
code
kotlin · 6 linesval repo = mockk<UserRepository>()
every { repo.findById(1L) } returns User(1L, "Ada")
every { repo.findById(2L) } returns null
assertEquals("Ada", repo.findById(1L)?.name)
assertNull(repo.findById(2L))go deeper
Can create mockk() and write a basic every { } returns and inject the mock.
Knows strict vs relaxed default behaviour and the returnsMany/throws/answers terminators.
Explains the reified type param, the recording DSL, and how bytecode/inline mocking handles final members.
Reasons about when mocking is the right isolation tool vs fakes/real objects, and the maintenance cost of over-stubbing.
## What a mock is A *mock* is a fake implementation of a type, created at runtime, whose behaviour you script. You use it to isolate the *class under test* from its collaborators (databases, HTTP clients, other services). ## Creating a mock: `mockk<T>()` MockK's entry point is the inline reified function `mockk<T>()`. The `<T>` type parameter is `reified`, so MockK knows the concrete type at runtime and can generate a proxy. ```kotlin interface UserRepository { fun findById(id: Long): User? } val repo: UserRepository = mockk() // type inferred from the val // or val repo = mockk<UserRepository>() // explicit type argument ``` By default `mockk()` produces a **strict** mock: calling any method that has *not* been stubbed throws `MockKException`. (A *relaxed* mock that returns defaults is a separate feature — outside this topic.) ## Stubbing: `every { } returns` You script behaviour with the `every { }` block. Inside the lambda you write the exact call you want to intercept; the value after `returns` is what that call yields. ```kotlin every { repo.findById(1L) } returns User(1L, "Ada") ``` Key stubbing terminators: - `returns x` — return a single value every time. - `returnsMany(listOf(a, b, c))` — return a, then b, then c on successive calls. - `throws SomeException()` — throw instead of returning. - `answers { ... }` — compute the result dynamically; the lambda can read arguments via `firstArg()`, `secondArg()`, or `arg<T>(index)`. ```kotlin every { repo.findById(any()) } answers { User(firstArg(), "dynamic") } ``` ## How it works under the hood MockK uses bytecode manipulation. Because Kotlin classes and methods are `final` by default, MockK ships a JVM agent / inline mocking engine so it can stub even final members without you opening them. This is why `mockk()` works on most Kotlin types out of the box. ## Typical test shape ```kotlin @Test fun returnsUserName() { val repo = mockk<UserRepository>() every { repo.findById(1L) } returns User(1L, "Ada") val service = UserService(repo) assertEquals("Ada", service.nameOf(1L)) } ``` ## Gotchas - A strict mock throws on any unstubbed call — stub everything the test exercises. - The `every` lambda is a *recording* DSL, not a real invocation; don't put assertions there. - One `every` overrides a previous one for the same call signature.
- What happens if you call a method on a strict mockk() that you never stubbed?It throws MockKException complaining there is no answer for that call. You must stub it or use a relaxed mock.
- How would you make a stubbed method throw instead of return?Use every { mock.call() } throws SomeException() instead of returns.
every { } returns is like programming a vending machine: you tell it 'when someone presses B4, dispense this snack'.
saying these in an interview costs you the question
- Thinking mockk() runs the real method body
- Putting assertions inside the every { } lambda
- Believing every call returns null/0 automatically (that's relaxed mocks)
- Confusing every (stubbing) with verify (checking)
- Claiming final Kotlin methods can't be mocked by MockK