skip to content

MockK's `mockk()` accepts a `name` parameter, as in `mockk<Repository>(name = "primaryRepo")`. What does that name actually affect, and when is it worth setting?

level: middleimportance: should knowfreq 30%

answer

  1. name = diagnostics only, no behaviour change
  2. default rendering `Type(#n)`, counter is global
  3. shows in "no answer found for: …" and verify dumps
  4. name when 2+ mocks of one type, or built in a loop
  5. `block` param stubs at creation; `mockkClass` for non-reified

basics

~20 s

It sets the mock's identity in its toString() and therefore in every MockK error and verification-failure message. Without it MockK prints a generated name like Repository(#1), which is ambiguous when a test holds several mocks of the same type.

solid answer

~50 s

`name` is purely diagnostic — it does not change behaviour, matching or verification. MockK renders a mock as `TypeName(#n)` by default, where `n` is a global counter, so two mocks of the same type in one test appear as `Repository(#1)` and `Repository(#2)` and you have to guess which is which from the ordinal. Passing `name = "primaryRepo"` makes failure text read `primaryRepo.find(1)` instead. That matters in three places: the "no answer found for: …" exception from a strict mock, verification failure dumps that list recorded calls per mock, and any place a mock leaks into an assertion message or a log line during the test. It is cheap and worth doing whenever a test has more than one mock of the same type — two repositories, a primary/replica pair, a list of handlers built in a loop — or in shared base-class fixtures where the failing mock is not visible in the failing test's own code.

code

kotlin · 6 lines
kotlin
val primary = mockk<Repository>(name = "primaryRepo")
val replica = mockk<Repository>(name = "replicaRepo")

replica.find(7)
// message reads: no answer found for: replicaRepo.find(7)
// instead of:    no answer found for: Repository(#2).find(7)

go deeper

for a junior

Know that name shows up in error messages and makes failures readable; it does not change what the mock does.

for a middle

Explain the default Type(#n) rendering, that the counter is global, and name the specific outputs it improves: unstubbed-call exceptions and verification dumps.

for a senior

Treat it as a debuggability practice — name mocks in shared fixtures, loops and parameterised tests where the failure message is the only diagnostic you get from CI.

for a principal

Fold it into a fixture convention: annotation-derived names by default, explicit name = for constructed collections, so that CI failure text is self-describing without anyone reading the test source.

## What the parameter is The full creation entry point in MockK is roughly: ```kotlin mockk<T>( name: String? = null, relaxed: Boolean = false, vararg moreInterfaces: KClass<*>, relaxUnitFun: Boolean = false, block: T.() -> Unit = {}, ): T ``` `name` is the first of those creation options and the least behavioural: it changes **how the mock identifies itself in text**, nothing else. Matching, stubbing, verification, equality and hashing are unaffected. ## What it changes A MockK mock overrides its string representation. By default it renders as the simple type name plus a global creation counter — `Repository(#1)`, `Repository(#2)`, `Clock(#3)`. Supply `name = "primaryRepo"` and it renders as `primaryRepo`. That string surfaces in the places where you are already in pain: 1. **Strict-mock failures.** Calling an unstubbed method on a plain (non-relaxed) mock throws a `MockKException` whose message starts `no answer found for:` followed by the rendered call — `Repository(#2).find(7)` versus `replicaRepo.find(7)`. With two mocks of the same type, the ordinal tells you nothing; the name tells you everything. 2. **Verification failures.** When `verify` fails, MockK prints the expected call and a dump of the calls it actually recorded, keyed by mock. Named mocks turn that dump into something you can read at a glance. 3. **Incidental leakage.** If the code under test logs a collaborator, or an assertion message interpolates one, you see the mock's rendering. A named mock keeps that legible. ## Why the default is awkward The `#n` counter is **global to the process, not per test**. Mocks created by earlier tests in the same JVM advance the counter, so the same mock is not reliably `#1` across runs, and you cannot map an ordinal in a CI log back to a line of code by counting. This is the concrete reason experienced people name mocks in fixtures: the ordinal is not a stable identifier. ## When to bother Name them when identification is genuinely at risk: - **Two or more mocks of the same type** in one test — primary/replica, source/target, inbound/outbound clients. - **Mocks created in a loop or a factory** — `List(3) { mockk<Handler>(name = "handler-$it") }` turns an unreadable dump into an indexed one. - **Shared fixtures / base classes**, where the failing mock was created far from the failing assertion. - **Parameterised tests**, where the failure message is often the only clue about which case blew up. Skip it for a single-mock test: `Repository(#1)` is unambiguous there, and a name adds noise. ## Related creation surface worth knowing - The `block` parameter lets you stub at creation: `mockk<Repo> { every { find(1) } returns account }` — the receiver of the block is the new mock. This keeps naming and initial stubbing in one expression. - `mockkClass(Repository::class, name = "primaryRepo")` is the non-reified sibling of `mockk<T>()`: same options, but the type is passed as a `KClass` value. Use it when the type is only known at runtime — for example a generic test helper that receives a `KClass` — since `mockk<T>()` needs a reified type at the call site. - MockK's annotation-driven setup derives a name from the annotated **property name**, which is why annotation-based fixtures are often readable without ever touching `name` explicitly. ## The interview point The answer that scores is: *it is diagnostics only; it replaces the generated `Type(#n)` rendering in error and verification output; the counter is global so it is not a stable identifier; name mocks when a test holds several of a type or builds them in a loop.* Saying "it makes MockK track the mock" or "it's required for verify" is the failure mode — nothing in MockK's matching depends on the name.

  • Does the mock's name take part in equality, matching or verification in any way?
    No. The name only changes the mock's textual rendering. Argument matching compares the actual arguments, verification is tracked per mock instance identity, and two mocks with the same name are still two unrelated mocks. Nothing in MockK looks a mock up by name.
  • How do you get readable mock names without passing `name` at every creation site?
    Use MockK's annotation-driven setup: annotating a property with `@MockK` and initialising with `MockKAnnotations.init(this)` derives the mock's name from the property name, so the field name you already chose becomes the diagnostic name. That covers most fixture code; explicit `name =` is then reserved for mocks built inline or in loops, where there is no property name to borrow.

saying these in an interview costs you the question

  • "The name is how MockK identifies the mock for verification" — verification is by instance identity; the name is cosmetic.
  • "Two mocks with the same name conflict / MockK throws" — names are not unique keys and nothing enforces uniqueness.
  • "The `#n` suffix is per test, so #1 is always the first mock in my test" — the counter is global to the JVM run.
  • "Naming a mock changes its default answers" — it changes nothing about stubbing or relaxation.

context