Mockito's InOrder handle has its own verifyNoMoreInteractions(), and there is also the static Mockito.verifyNoMoreInteractions(mock). How do the two differ, and when does one pass while the other fails?
answer
- InOrder version = nothing AFTER the cursor
- static version = nothing unverified ANYWHERE
- foo(); bar(); verify bar -> InOrder passes, static fails
- greedy atLeast hides trailing calls
- both are over-specification hazards
basics
~20 sinOrder.verifyNoMoreInteractions() only fails if some interaction happened after the last invocation verified through that handle; earlier unverified calls are fine. The static form is order-blind and fails on any unverified invocation on the mock, wherever it sits.
solid answer
~50 sThe static verifyNoMoreInteractions(mock) is exhaustive: it walks every recorded invocation on that mock and fails if any of them was never verified, regardless of position. It is the strict 'this test accounts for everything' assertion. The InOrder version is positional. It asserts only that nothing happened after the last invocation the handle verified. Anything before or between the verified calls is tolerated, exactly like ordinary in-order gaps. So with a mock receiving foo() then bar(), where the handle verified only bar(): inOrder.verifyNoMoreInteractions() passes, because foo() precedes the last verified call; the static verifyNoMoreInteractions(mock) fails, because foo() is unverified. Use the InOrder form to say 'the protocol ends here — no trailing calls', and the static form to say 'this mock did nothing else at all'. Both are blunt instruments: in real suites prefer verifying the interactions you actually care about, since exhaustive assertions break on every harmless new call.
code
java · 8 linesmock.foo();
mock.bar();
InOrder inOrder = inOrder(mock);
inOrder.verify(mock).bar();
inOrder.verifyNoMoreInteractions(); // passes: foo() came before bar()
Mockito.verifyNoMoreInteractions(mock); // fails: foo() was never verifiedgo deeper
Not core; just know the static form means 'nothing unverified on this mock'.
State the positional versus exhaustive distinction and give the foo/bar example.
Explain why the ordered form is scoped after the cursor, how consumption modes change what it catches, and when each is justified.
Treat exhaustive interaction assertions as a coupling decision: they encode 'no side effects' contracts and should be deliberate and rare, not a habit.
## Two different questions Mockito marks invocations as verified as you assert on them. Both no-more-interactions checks look at what is left over, but they scope the search differently. The static Mockito.verifyNoMoreInteractions(mock...) scans the entire invocation list of each mock and fails on the first invocation with no verified mark, printing it as an 'unwanted' interaction. Position is irrelevant. It is the exhaustive claim: every call this mock received was accounted for by this test. inOrder.verifyNoMoreInteractions() uses the handle's ordering context. It asks whether any invocation on the handle's mocks occurred after the last position the cursor reached. Invocations before that point — including ones the test deliberately skipped over — do not matter. It is the positional claim: after the protocol steps I verified, nothing more happened. ## The canonical divergence mock.foo(); mock.bar(); with InOrder inOrder = inOrder(mock); inOrder.verify(mock).bar(); inOrder.verifyNoMoreInteractions() passes: foo() is earlier than the last verified invocation, so it is outside the window this check looks at. Mockito.verifyNoMoreInteractions(mock) fails, reporting foo() as an unwanted interaction because nothing verified it. The same test, the same mock, opposite verdicts — which is the whole point of the question. ## Why the InOrder version is scoped that way Ordered verification is intentionally tolerant of gaps so that adding an unrelated interaction does not break unrelated ordering assertions. An ordered no-more-interactions that failed on earlier gaps would contradict that tolerance and make every InOrder test exhaustive by accident. Scoping it to 'after the cursor' gives you a way to close the tail of a protocol — 'begin, save, commit, and then nothing' — without claiming anything about what happened before or between those steps. ## Interaction with consumption modes Because it is defined in terms of verified invocations and cursor position, it interacts with how each mode consumes. After inOrder.verify(mock, calls(2)).poll(), surplus polls stay unverified, so a trailing surplus poll will fail inOrder.verifyNoMoreInteractions(). After atLeast(2), all matching polls were consumed greedily, so the same trailing poll is silently accepted. Choosing the mode therefore changes what the closing assertion can still catch. ## Practical use and cautions Both assertions are over-specification hazards. The static form turns every new interaction with the mock — an added log, a getter, a metrics call — into a failing test in a place unrelated to the change, which is why many teams restrict it to a few tests that genuinely assert 'no side effects', and prefer verifyNoInteractions(mock) for the simpler 'this collaborator was never touched' claim. The InOrder form is narrower and usually safer, since it only forbids a tail. A note on stubbing: with strict stubs (the default under Mockito's JUnit 5 extension), unused stubbings are already reported, so blanket no-more-interactions assertions add less value than they used to. Also remember that verified-ness is per invocation, so a mock reused across phases of a long test can produce confusing results — a shorter test, or clearing the mock between phases, is usually the better answer than a stronger closing assertion.
- Why would a team prefer the InOrder form as the default closing assertion?Because it only forbids interactions after the protocol steps under test, it does not break when someone adds an unrelated call earlier in the flow. That keeps the test asserting the tail of a contract rather than an exhaustive transcript, which is the more stable claim as the production code evolves.
- How does verifyNoInteractions(mock) relate to these two?It is the strongest and simplest of the three: it fails if the mock received any invocation at all, verified or not, and is meant for 'this collaborator must not be touched on this path'. The two no-more-interactions checks are about leftovers relative to what a test already verified, so they only make sense after some verification has happened.
saying these in an interview costs you the question
- Saying the two forms are equivalent, just written differently
- Expecting the InOrder form to fail on unverified calls that happened earlier
- Believing the static form respects the order of verification statements
- Using either as a routine closing line on every test without weighing brittleness
- Confusing it with verifyNoInteractions, which forbids any interaction at all