What is the difference between mockk(relaxed = true) and mockk(relaxUnitFun = true), and when would you choose relaxUnitFun?
answer
- relaxed = ALL methods relaxed
- relaxUnitFun = only Unit/void relaxed
- Value-returning methods still throw under relaxUnitFun
- Best for loggers/publishers/void save
- Middle ground: no void boilerplate, no silent wrong defaults
basics
~10 srelaxed = true auto-answers every method. relaxUnitFun = true only auto-answers methods that return Unit (void); methods that return a real value still throw unless you stub them.
solid answer
~40 srelaxed = true relaxes all methods: both Unit-returning and value-returning calls get auto defaults. relaxUnitFun = true is narrower — it only relaxes functions whose return type is Unit, so you don't have to write every { mock.log(any()) } just? Unit returns; but any value-returning method (Int, String, a domain type) stays strict and throws MockKException if unstubbed. Choose relaxUnitFun when a collaborator has fire-and-forget void methods (loggers, event publishers, repository.save returning Unit) that you don't care about, while still being forced to explicitly stub the methods whose return values your test logic actually depends on. It's the safest balance: no boilerplate for void calls, no silent wrong defaults for meaningful returns. There's also a global flag MockKSettings / @MockKExtension you can configure, but the per-mock parameter is the common form.
code
kotlin · 10 linesinterface Audit {
fun record(event: String) // returns Unit
fun pending(): Int // returns Int
}
val a = mockk<Audit>(relaxUnitFun = true)
a.record("login") // OK, no stub needed (Unit)
// a.pending() // throws MockKException — must stub:
every { a.pending() } returns 3
verify { a.record("login") }go deeper
Knows relaxUnitFun handles void methods so you don't stub returns Unit calls.
Precisely states that only Unit returns are relaxed and value methods still throw; picks it for logger/publisher collaborators.
Frames it as the safest balance between brittleness and silent defaults; knows global config options exist.
Defines a team default (e.g., relaxUnitFun over relaxed) to keep tests failing loudly on missing value stubs.
## Two relaxation knobs `mockk()` takes boolean parameters that control auto-stubbing: - `relaxed = true` — relax **all** functions (every return type gets a default). - `relaxUnitFun = true` — relax **only** functions returning `Unit` (Kotlin's void). Value-returning functions stay strict. `Unit` is Kotlin's type for "returns nothing meaningful" — like `void` in Java. Many side-effecting methods (`log()`, `publish(event)`, `save(entity)`) return `Unit`. ## Why relaxUnitFun exists With a strict mock, even a void call throws: ```kotlin val logger = mockk<Logger>() logger.info("hi") // throws: no answer found ``` You'd have to write `every { logger.info(any()) } returns Unit` — pure noise, since you don't care about a void return. `relaxUnitFun = true` removes exactly that noise: ```kotlin val logger = mockk<Logger>(relaxUnitFun = true) logger.info("hi") // OK, does nothing // but: val n = logger.lineCount() // Int return -> STILL throws, must stub ``` ## Contrast table | Call return type | strict mockk() | relaxUnitFun=true | relaxed=true | |---|---|---|---| | `Unit` (void) | throws | auto (no-op) | auto (no-op) | | `Int`/`String`/obj | throws | **throws** | auto default | ## When to choose relaxUnitFun - Collaborator with many side-effecting void methods you only `verify`. - You WANT a hard failure if your test accidentally reads an unstubbed value method (catches typos and missing setup). It is the recommended middle ground: less brittle than fully strict for void calls, but it does **not** mask meaningful return values the way `relaxed = true` does. ## Global configuration You can flip relaxation suite-wide via `@MockKExtension` configuration or `MockKSettings`, but prefer the explicit per-mock parameter for clarity.
- If a method returns Unit but you set relaxed = false and relaxUnitFun = false, what happens when you call it unstubbed?It throws MockKException — strict mocks reject even Unit-returning calls until they are stubbed or verified-after-call patterns are used.
- Does relaxUnitFun affect suspend functions returning Unit?Yes; a suspend fun returning Unit is relaxed too. You'd verify it with coVerify, but the unit-relaxation applies the same.
relaxed = true is a blanket amnesty for all calls; relaxUnitFun = true pardons only the harmless void calls and still prosecutes the ones that hand back data.
saying these in an interview costs you the question
- Saying relaxUnitFun relaxes value-returning methods too
- Claiming Unit methods never throw on strict mocks (they do)
- Confusing relaxUnitFun with relaxed and using it expecting Int defaults
- Thinking you must stub Unit methods even with relaxUnitFun = true