skip to content

every / verify

The core loop is mockk to create, every to stub, verify to assert interactions, with matchers like any, eq, and slot for capturing arguments. Capturing an argument to assert on it later is the technique worth demonstrating.

part ofKotlinoverview, primer and where to startread it →
on this pageshow

questions

5

How do you create a mock with MockK and make one of its methods return a fixed value?

level: juniorimportance: must knowfreq 85%

answer

  1. mockk<T>() = create fake
  2. every { } returns = script return value
  3. strict by default: unstubbed call throws
  4. returnsMany / throws / answers terminators
  5. reified type param

basics

~10 s

Create 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 s

Use 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 lines
kotlin
val 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

for a junior

Can create mockk() and write a basic every { } returns and inject the mock.

for a middle

Knows strict vs relaxed default behaviour and the returnsMany/throws/answers terminators.

for a senior

Explains the reified type param, the recording DSL, and how bytecode/inline mocking handles final members.

for a principal

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

context

open as a page

How do you verify with MockK that a method was (or was not) called, and how many times?

level: middleimportance: must knowfreq 80%

basics

~20 s

Use verify { mock.method(args) } after the action to check the call happened. You can also pass exactly = n, atLeast, atMost, or exactly = 0 to assert how many times it ran or that it never ran.

open as a page

Explain MockK argument matchers any() and eq(). When must you use a matcher, and what is the rule about mixing matchers with literals?

level: middleimportance: should knowfreq 65%

basics

~20 s

any() matches any argument; eq(x) matches a value equal to x. If you use a matcher for one argument in a call, you must use matchers for all arguments of that call — you can't mix matchers with plain values.

open as a page

How do slot() and capture() work in MockK, and when would you capture an argument instead of just matching it?

level: seniorimportance: should knowfreq 55%

basics

~10 s

A slot is a container. You pass capture(slot) where an argument goes, and MockK stores the real value the code passed in. Afterwards you read slot.captured to assert on or inspect that value.

open as a page

Compare returns, returnsMany, throws, and answers { } as stub terminators in MockK. When is answers { } the right choice?

level: seniorimportance: nice to knowfreq 45%

basics

~20 s

returns gives one fixed value, returnsMany gives values in sequence, throws makes the call fail, and answers { } computes the result with a lambda. Use answers when the return must depend on the call's arguments.

open as a page