What is the difference between verifyNoInteractions and verifyNoMoreInteractions, and how do you use each correctly?
answer
- NoInteractions = mock never used at all
- NoMoreInteractions = nothing left unverified, run last
- NoMoreInteractions depends on prior verify() calls
- brittle — use sparingly
- strict stubs reduce the need; ignoreStubs for stubbed calls
basics
~10 sverifyNoInteractions(mock) asserts the mock was never used at all. verifyNoMoreInteractions(mock) is called after your verify() calls and asserts there were no leftover, unverified interactions beyond those.
solid answer
~50 sBoth assert about the absence of interactions, but at different points. verifyNoInteractions(mock) (which replaced the older verifyZeroInteractions) asserts the mock was completely untouched — no method on it was ever called. You use it when a collaborator should be bypassed entirely on a given path, e.g. on a validation-failure branch the emailSender must never be invoked. verifyNoMoreInteractions(mock) is placed after a series of verify() calls; it asserts that every interaction that occurred has now been verified — there are no extra, unaccounted-for calls. It is a strictness ratchet: it catches calls you forgot about or didn't intend. The risk is brittleness: verifyNoMoreInteractions fails when someone adds a harmless new interaction, so apply it deliberately, not reflexively. Modern Mockito's strict stubs (the default in JUnit5 MockitoExtension) already flag unused stubs, reducing the need to sprinkle verifyNoMoreInteractions everywhere.
go deeper
Knows verifyNoInteractions means the mock was not used; may not yet distinguish it from verifyNoMoreInteractions.
Correctly uses each: NoInteractions for a skipped collaborator, NoMoreInteractions as the final exhaustive check.
Understands the brittleness trade-off, places NoMoreInteractions last, and handles stubbed-call counting with ignoreStubs; knows the verifyZeroInteractions deprecation.
Weighs exhaustive interaction pinning against maintainability across the suite, leans on strict stubs, and codifies when 'exactly these calls' is a contract worth enforcing.
## The interaction log Every Mockito mock keeps a log of the calls made to it. Each `verify(mock).foo()` you write **marks** the matching call(s) as 'verified'. The two methods below reason about that log as a whole. ## verifyNoInteractions(mock...) Asserts the mock was **never touched at all** — zero calls of any method. It is the strongest 'this should not be used' statement. ```java service.validateAndSave(invalidInput); verifyNoInteractions(emailSender); // never emailed on invalid input ``` It takes one or more mocks. It is independent of any prior `verify` calls. (It replaced the deprecated `verifyZeroInteractions`, which did the same thing.) ## verifyNoMoreInteractions(mock...) Asserts that **every** interaction on the mock has already been verified — i.e. there is **nothing left over**. It is meant to be the **last** assertion, after your expected `verify` calls: ```java verify(repo).findById(1L); verify(repo).save(user); verifyNoMoreInteractions(repo); // findById + save were the ONLY calls ``` If the code also called, say, `repo.delete(...)` that you didn't verify, this fails. If you place it *before* a `verify`, it will fail because that call is still unverified. ## Side-by-side | | verifyNoInteractions | verifyNoMoreInteractions | |---|---|---| | Asserts | mock untouched, period | no *unverified* calls remain | | Relation to verify() | independent of them | depends on them; run last | | Typical use | collaborator should be skipped | exhaustively pin a mock's calls | ## Why be careful `verifyNoMoreInteractions` makes the test **exhaustive**: any new interaction — even a benign logging or metrics call — breaks it. That couples the test to the full call shape of the code, which is brittle on refactor. The Mockito team itself recommends using it sparingly, not as a default in every test. ## Interaction with strict stubs Since JUnit 5's `MockitoExtension` defaults to **strict stubs** (`Strictness.STRICT_STUBS`), unused stubbings already raise `UnnecessaryStubbingException`, and argument mismatches are reported. This catches a lot of what people historically used `verifyNoMoreInteractions` for, so you need it less. Reach for `verifyNoMoreInteractions` only when 'these are *exactly* the calls and no others' is a genuine, valuable contract. ## Gotcha: stubbed calls count A call that was *stubbed* and then invoked still appears in the interaction log. If you `when(repo.findById(1)).thenReturn(...)` and the code calls it, `verifyNoMoreInteractions(repo)` will complain about that call unless you either `verify` it or mark it via `ignoreStubs(repo)`.
- Why might verifyNoMoreInteractions fail even though all your real assertions pass?Because the code made an interaction you didn't verify — often a stubbed call that was invoked, or a newly added logging/metrics call. Either verify it, use ignoreStubs(mock), or drop the exhaustive check.
- What replaced verifyZeroInteractions and why?verifyNoInteractions replaced it for clearer naming; the old method is deprecated. Both assert the mock was never touched.
saying these in an interview costs you the question
- Using verifyNoMoreInteractions before the verify() calls it depends on (it will fail)
- Sprinkling verifyNoMoreInteractions everywhere, creating refactor-brittle tests
- Confusing the two: thinking verifyNoMoreInteractions means 'mock never used' (that is verifyNoInteractions)
- Forgetting stubbed-then-called methods count as interactions (use ignoreStubs)