In MockK, how do you assert that a mocked method was called a specific number of times, and what does verify { ... } default to when you don't pass a count?
answer
- exactly = n is a named param outside the lambda
- bare verify = atLeast = 1 (not exactly once)
- exactly = 0 means never called
- no verifyNever API exists
- count is over matching invocations
basics
~20 sUse verify(exactly = n) { mock.method() } to require exactly n calls. A plain verify { ... } with no count means "at least one call" (atLeast = 1), so it fails only if the call never happened.
solid answer
~40 sMockK's verify takes named parameters that control the count. verify(exactly = n) { mock.foo() } asserts the matching call happened exactly n times; verify(exactly = 0) { mock.foo() } asserts it never happened (a negative assertion). A bare verify { mock.foo() } defaults to atLeast = 1, i.e. one or more calls. The lambda body uses the same argument matchers (any(), eq(), capturing slots) as every. Counts apply per matching invocation, so verify(exactly = 2) { mock.foo(any()) } passes only when foo was invoked twice with any argument. Use exactly = 0 instead of a separate "never called" API — MockK has no verifyNever; the count expresses it.
code
kotlin · 6 linesval repo = mockk<Repo>(relaxed = true)
service.process(order)
verify(exactly = 1) { repo.save(order) } // precisely once
verify(exactly = 0) { repo.delete(any()) } // never
verify { repo.audit(any()) } // at least once (default)go deeper
Knows verify(exactly = n) and that exactly = 0 means never called.
Knows the bare-verify default is atLeast = 1 and that counts are over matching invocations only.
Explains why there is no verifyNever and how matchers in the lambda affect what gets counted.
Frames exactly vs atLeast/atMost as a deliberate API design and advises teams when exact counts make tests brittle vs precise.
## What `verify` does `verify` is MockK's assertion that recorded calls on a **mock** (a fake object whose behavior you stubbed with `every`) actually occurred. It does **not** stub anything; it checks history after the code under test ran. ## The `exactly` parameter The count is passed as a **named argument** to `verify`, not inside the lambda: ```kotlin val repo = mockk<Repo>(relaxed = true) service.save(item) verify(exactly = 1) { repo.insert(item) } // exactly one call verify(exactly = 0) { repo.delete(any()) } // never called (negative) verify(exactly = 3) { repo.touch() } // precisely three ``` - `exactly = 0` is the idiomatic **"never happened"** assertion. MockK has **no** `verifyNever`; you express it with the count. - The lambda holds the **call expectation** with argument matchers: `any()`, `eq(x)` (the default for literals), `range(...)`, or a capturing `slot()`. ## Default when no count is given A bare `verify { repo.insert(item) }` is equivalent to `verify(atLeast = 1)` — it passes if the call occurred **one or more** times and fails only when it never occurred. So an unparameterised `verify` is **not** an exact-once check; if you need exactly-once, write `exactly = 1`. ## Counting semantics The count is over **invocations matching the lambda**. `verify(exactly = 2) { repo.find(any()) }` requires two calls to `find` with any argument. If `find` was called twice but with arguments that don't match your matcher, those calls don't count. ## Relation to other modes `exactly` is one of several count modes; the others are `atLeast`, `atMost`, and a `timeout`. They are mutually meaningful named params on the same `verify` overload.
- How do you assert a call never happened?verify(exactly = 0) { mock.method(...) }. There is no verifyNever; the zero count is the negative assertion.
- Does verify(exactly = 1) check the order relative to other calls?No. exactly only counts matching invocations of that one expectation. Ordering across calls needs verifyOrder or verifySequence.
Like checking a doorbell log: exactly = 3 says the bell rang precisely three times, exactly = 0 says it never rang.
saying these in an interview costs you the question
- Thinking a bare verify { } means 'called exactly once'
- Inventing a verifyNever() function
- Putting the count inside the lambda instead of as a named param
- Confusing exactly = 0 with confirmVerified