skip to content

What does Mockito's verifyNoMoreInteractions do, how does it differ from asserting a mock was never used at all, and what failure does it produce?

level: middleimportance: should knowfreq 44%

answer

  1. 'no more' = nothing left unverified
  2. verify marks invocations as consumed
  3. no prior verifies -> same as zero interactions
  4. stubbed calls count and need excluding
  5. exhaustive = brittle; use sparingly

basics

~20 s

verifyNoMoreInteractions(mock) asserts that every invocation recorded on the mock has already been verified by earlier verify calls in the test - it closes off leftovers. Asserting the mock was never used at all is a different, unconditional check. Leftovers fail with a no-interactions-wanted error naming the unverified call.

solid answer

~50 s

`verifyNoMoreInteractions(mock)` is a *relative* assertion: it walks the mock's recorded invocations and fails if any of them was not already consumed by a preceding `verify`. Placed at the end of a test, it turns a set of positive verifications into an exhaustive specification of everything that touched that collaborator. By contrast, the never-used-at-all assertion is absolute - it fails on the first invocation regardless of what the test verified. Semantically, running it on a mock with no prior verifications is the same as demanding zero interactions. The failure is a no-interactions-wanted error listing the unverified invocation and its stack trace. Two caveats. First, calls the code makes to *stubbed* methods count as interactions too, so an exhaustive check often trips on stubbing traffic unless those calls are excluded. Second, exhaustiveness means every new call on that collaborator breaks the test - which is why the Mockito documentation itself advises using it sparingly rather than at the end of every test.

code

java · 7 lines
java
@Test
void publishesExactlyOneEventAndNothingElse() {
    service.confirm(order);

    verify(publisher).publish(new OrderConfirmed("A"));
    verifyNoMoreInteractions(publisher);   // a second publish or any other call fails here
}

go deeper

for a junior

Know that it means 'nothing left unverified' and that it comes after the positive verify calls.

for a middle

Explain that verify consumes matching invocations, contrast the relative and absolute forms, and mention that stubbed calls count too.

for a senior

Argue about when exhaustiveness is worth its brittleness, and describe how strict stubs already cover part of the same ground.

for a principal

Frame it as a policy question for the suite: which collaborator protocols are stable enough to specify exhaustively, and what the failure ergonomics cost the team over time.

## Relative versus absolute Mockito has two whole-mock assertions and they differ in what they take into account. - The absolute one asserts the mock recorded **no invocations at all**, independent of anything else the test did. - `verifyNoMoreInteractions(mock)` asserts that **no invocation remains unverified**. Each successful `verify` marks the invocations it matched as verified; this call then fails if any unmarked invocation is left. So the same test can pass `verifyNoMoreInteractions` with ten recorded calls, provided ten matching `verify` assertions preceded it. And with no preceding verifications, the two assertions coincide. ```java verify(repo).save(order); verify(repo).flush(); verifyNoMoreInteractions(repo); // fails if the code called anything else on repo ``` It accepts varargs, so several collaborators can be closed off at once. ## What it buys you Exhaustiveness. Positive verifications alone are open-ended: they prove certain calls happened but tolerate any number of additional ones. Closing the set converts the test into a full statement of the collaborator's protocol for that scenario, which catches genuinely interesting regressions - a duplicated publish, an accidental second save inside a loop, a stray audit write added on a path where it must not happen. That is real value in a narrow set of places: a small port whose protocol is the point of the test, an outbound-effect boundary where surprises are defects, or a regression test written specifically to pin down "and nothing else happened". ## What it costs Every future call on that collaborator, however harmless, fails the test - and it fails at the exhaustive-check line, far from the change that caused it, with a message about an unverified invocation rather than about broken behaviour. Sprinkled through a suite, it produces a maintenance tax that is paid by people who did not write the tests. Stubbing traffic makes this worse. If the code under test calls a method you stubbed to make the scenario run, that call is recorded like any other and is unverified unless you also wrote a `verify` for it. Tests then acquire verifications whose only purpose is to appease the exhaustive check, which is noise. Mockito provides a way to exclude stubbed invocations from the check for exactly this reason. ## Reading the failure A violation raises a no-interactions-wanted error that names the unverified invocation, prints its stack trace, and shows the mock involved. The right first move is to look at that call and ask a design question rather than a mechanical one: *should this call exist?* If yes, either add a real verification for it or drop the exhaustive check; if no, you have found the bug the assertion was written to catch. ## Interaction with strictness Modern Mockito runs strict stubs by default under the JUnit 5 extension. Strict stubs already report unused stubbings and argument mismatches at the end of the test, which removes one of the historical motivations for exhaustive verification ("catch calls I did not expect"). It does not report *extra unstubbed calls* on a mock, so the two mechanisms are complementary - but the residual gap is smaller than people assume, which is another argument for using exhaustive checks deliberately rather than habitually. ## Practical rule Use a positive `verify` for the effects that matter, a targeted negative assertion for the effect that must not happen, and reserve `verifyNoMoreInteractions` for the few tests whose actual subject is the completeness of an interaction protocol.

  • If a test calls verifyNoMoreInteractions(mock) without any preceding verify on that mock, what does it assert?
    Effectively that the mock was never used, since with nothing verified every recorded invocation is a leftover. It is the wrong way to say it, though: the absolute assertion states the intent directly and produces a clearer message, while the relative form invites a later reader to assume some verification was meant to precede it.
  • Your team adds verifyNoMoreInteractions at the end of every test as a policy. What problems do you predict?
    Widespread breakage on harmless changes - an added log call, a metric, an extra read - each failing at the exhaustive line rather than where behaviour changed. Tests also accumulate verifications written purely to satisfy the check, especially for stubbed calls the scenario needs, which dilutes the signal about what the test is really specifying. I would keep it for protocol-focused tests and remove it elsewhere.

saying these in an interview costs you the question

  • Treating verifyNoMoreInteractions as a synonym for 'the mock was never used'
  • Not realising that calls to stubbed methods count as unverified interactions
  • Adding verifications purely to silence the exhaustive check
  • Using it in every test as a default hygiene step
  • Assuming it verifies ordering as well as completeness

context