In MockK, what does creating a mock with mockk<T>(relaxed = true) do, and how does it differ from a plain mockk<T>()?
answer
- Strict = throws on unstubbed; relaxed = auto-default
- 0, false, "", empty collection
- Object returns -> nested relaxed mock
- relaxed = true reduces stubbing boilerplate
- Downside: hides unexpected calls
basics
~10 sA relaxed mock auto-answers every call with a default value, so you don't have to stub each method. A plain mock throws if you call a method you never stubbed.
solid answer
~30 smockk<T>() is strict: calling any method that has no matching every { } stub throws MockKException ("no answer found"). mockk<T>(relaxed = true) is permissive: MockK auto-generates a default return for every unstubbed call — 0 for Int, false for Boolean, "" for String, empty collections, and a nested relaxed mock for arbitrary object return types. You still override specific calls with every { mock.foo() } returns ... when a test needs a real value. Relaxed mocks reduce boilerplate when you only care about a few methods, but they hide unexpected interactions, so prefer strict mocks plus explicit stubs when behavior matters.
code
kotlin · 10 linesval strict = mockk<UserRepo>()
// strict.count() // throws MockKException: no answer found
val relaxed = mockk<UserRepo>(relaxed = true)
println(relaxed.count()) // 0 (auto default)
println(relaxed.findAll()) // [] (empty list)
val user = relaxed.findById(1) // a nested relaxed mock<User>
every { relaxed.count() } returns 42
println(relaxed.count()) // 42 (override wins)go deeper
Knows relaxed = true avoids stubbing every method and returns sensible defaults.
Lists the concrete default values and knows nested object returns become relaxed mocks; can still override with every.
Articulates the trade-off (hidden interactions) and recommends strict-by-default, using relaxUnitFun as a middle ground.
Sets team conventions on when relaxed is acceptable, weighing test brittleness vs. silent-default risk across a suite.
## What a mock is A **mock** is a stand-in object that records calls and returns whatever you tell it. In MockK you create one with `mockk<Type>()`. A **stub** is a programmed answer you attach with the `every { ... } returns ...` DSL. ## Strict mocks (the default) `mockk<Repo>()` is **strict**. If you call a method that has no matching `every` stub, MockK throws a `MockKException` like *"no answer found for: Repo(#1).find(...)"*. This forces you to be explicit about every interaction — good for catching surprises, verbose when you don't care. ## Relaxed mocks `mockk<Repo>(relaxed = true)` makes the mock **relaxed**: any unstubbed call returns an auto-generated default instead of throwing. Default values MockK picks: - Numbers → `0` / `0.0` - `Boolean` → `false` - `String` → `""` (empty string) - `Unit` → returns normally - Collections (`List`, `Set`, `Map`) → empty - Any other object type → a **new relaxed mock of that type** (recursively) - Nullable types → MockK returns a non-null relaxed default, not `null`, unless you stub `returns null`. You can still override individual methods: ```kotlin val repo = mockk<UserRepo>(relaxed = true) every { repo.count() } returns 5 // explicit val u = repo.findById(1) // unstubbed -> relaxed mock<User> println(repo.count()) // 5 ``` ## When to use which - **Strict + explicit stubs**: when the test asserts on specific return values or you want failures on unexpected calls. This is the recommended default. - **Relaxed**: when the collaborator has many methods but only a couple matter, or you mock something you only `verify` against and never read a return from. ## Caveat Relaxed mocks **hide bugs**: a typo'd or unexpected call silently returns `0`/`""` instead of failing loudly. Reach for `relaxUnitFun = true` (see other questions) when you only need void/`Unit` methods relaxed but want returning methods to stay strict.
- What does a relaxed mock return for a method whose return type is a custom data class?A new relaxed mock instance of that data class type, generated recursively — not null and not a real constructed object.
- Can you still stub a single method on a relaxed mock?Yes. every { } / returns overrides the auto default for that specific call; everything else stays relaxed.
A strict mock is a vending machine that errors unless you pre-load a slot; a relaxed mock dispenses a blank default for any button you press.
saying these in an interview costs you the question
- Claiming a relaxed mock returns null by default (it returns a non-null relaxed default)
- Saying a plain mockk() also auto-stubs returns (it throws instead)
- Thinking relaxed disables verification — you can still verify { } calls
- Believing relaxed makes the mock call real methods (that's spyk, not relaxed)