Code under test calls a mock's a(), then b(), then c(). A Mockito test creates an InOrder handle with inOrder(mock) and verifies only a() and then c() through it. Does that pass, and what exactly is such an ordered verification asserting about the sequence?
answer
- subsequence, gaps allowed
- cursor only moves forward
- reverse order is what fails
- counts are evaluated from the cursor on
- add verifyNoMoreInteractions to tighten
basics
~20 sIt passes. Mockito's InOrder asserts a subsequence: the verified calls must appear in the given relative order, but any number of unverified calls may occur before, between or after them. It never asserts that nothing else happened.
solid answer
~40 sIt passes. InOrder keeps a cursor into the recorded invocations; each inOrder.verify searches forward from the cursor for a match and then advances past it. Because the search skips non-matching invocations, b() is simply stepped over. So the assertion is 'a() happened, and c() happened at some point after it' — a relative-order (subsequence) claim, not an exact transcript. That is deliberate: tests stay robust when unrelated interactions are added. What it does rule out is the reverse order: verifying c() then a() fails, because after the cursor has passed c() there is no later a(), and Mockito reports a verification-in-order failure. If you do want 'and nothing else', you tighten it explicitly — inOrder.verifyNoMoreInteractions() to forbid anything after the last verified call, or verifyNoMoreInteractions(mock) for the strict whole-mock version.
code
java · 9 linesmock.a(); mock.b(); mock.c();
InOrder inOrder = inOrder(mock);
inOrder.verify(mock).a();
inOrder.verify(mock).c(); // passes: b() is skipped
InOrder reversed = inOrder(mock);
reversed.verify(mock).c();
reversed.verify(mock).a(); // fails: no a() after c()go deeper
Answer that it passes and that InOrder only checks relative order, ignoring calls you did not verify.
Explain the forward cursor, the subsequence guarantee, and how to tighten it with a no-more-interactions assertion.
Add that counts are scoped from the cursor onward, describe the distinct in-order failure message, and discuss robustness versus strictness.
Argue the design intent: tolerant subsequences keep interaction tests from ossifying, so strictness should be opt-in and justified per test.
## The cursor model An InOrder handle holds an ordering context: essentially a position in the merged, chronologically ordered list of invocations across the mocks it was given. Each inOrder.verify(mock).x() scans forward from that position for the first invocation that matches the method and argument matchers. On a match it marks that invocation verified-in-order and moves the position just past it. On no match it throws a VerificationInOrderFailure. This single rule produces all the observed behaviour. Verifying a() then c() over the sequence a, b, c: a matches at index 0, cursor moves to 1; c is searched from index 1 and found at 2. Pass. Verifying c() then a(): c matches at 2, cursor moves to 3; a is searched from index 3, nothing left, fail. Verifying a() then b() then c(): also passes, since matches are found in increasing positions. ## Subsequence, not transcript The formal statement is that the verified calls must form a subsequence of the actual invocation sequence. Gaps are free — before the first verified call, between any two, and after the last. This is a design choice with a clear payoff: adding a new interaction (a log call, a metrics counter, an extra getter) does not break existing ordering tests. The cost is that an InOrder test alone can never tell you 'these and only these things happened', which surprises people who read it as a script. ## Making it stricter when you mean it Two tools tighten the claim. inOrder.verifyNoMoreInteractions() asserts that nothing happened after the last verified invocation, which turns the test into 'this prefix pattern, then nothing'. The static verifyNoMoreInteractions(mock) is stronger and order-insensitive: it fails if any invocation on that mock is unverified, including b() sitting in a gap. Choosing between them is exactly the choice between 'no trailing surprises' and 'exhaustive'. ## Counting interacts with the cursor Modes composed into an ordered verification are also evaluated from the cursor forward, not over the whole history. inOrder.verify(mock, times(2)).x() means two matching calls in the remaining part of the sequence. This is why an ordered times(n) can fail on a mock where the plain times(n) passes, and vice versa: they are counting over different ranges. The dedicated calls(n) mode exists for the non-greedy version of this. ## Failure messages Ordered failures read differently from plain ones: Mockito reports 'Verification in order failure' with the wanted invocation and often the actual invocation it found instead, plus the location of the previously verified call. Recognising that header is a quick way to know you are looking at an ordering problem rather than a missing call — the same method may well have been invoked, just not in the position you claimed. ## Practical guidance Verify only the steps whose relative order is contractual and let everything else fall into the gaps; that keeps the test expressing intent (lock before mutate, begin before commit) rather than transcribing an implementation. If a reviewer reads the test as an exhaustive script, either add the explicit no-more-interactions assertion or rename the test so the weaker claim is obvious.
- How do you turn that ordering test into 'a(), then c(), and nothing after that'?Append inOrder.verifyNoMoreInteractions() after the last ordered verification. It fails if any interaction with the handle's mocks occurred after the last verified invocation, while still tolerating the unverified b() that happened earlier. For a fully exhaustive claim you would instead use the static verifyNoMoreInteractions(mock), which rejects b() as well.
- Why can inOrder.verify(mock, times(2)).x() fail when verify(mock, times(2)).x() passes?The ordered form counts only matching invocations at or after the handle's current cursor, whereas the plain form counts every matching invocation ever recorded on the mock. If one of the two calls happened before an already-verified invocation, it is behind the cursor and no longer counted, so the ordered check sees only one.
Like proving someone visited Paris before Rome from passport stamps: other countries in between do not matter, only that Paris is stamped earlier.
saying these in an interview costs you the question
- Expecting the test to fail because b() was not verified
- Describing InOrder as asserting the exact, complete call sequence
- Thinking the cursor can move backwards to find an earlier match
- Assuming ordered times(n) counts over the mock's whole history
- Believing verifyNoMoreInteractions is implied by using InOrder