You need a test to prove that a mocked collaborator's open() method was called before its write() method. How do you express that ordering in Mockito, and why are two ordinary verify() calls not enough?
answer
- InOrder inOrder = inOrder(mocks)
- verify through the handle, not statically
- cursor moves forward, never backward
- spans multiple mocks
- subsequence, gaps allowed
basics
~20 sCreate an ordering handle with InOrder inOrder = inOrder(mock), then call inOrder.verify(mock).open() followed by inOrder.verify(mock).write(...). Plain verify() only checks that each call happened at all; it ignores sequence, so it passes even if write ran first.
solid answer
~50 sOrdinary verify(mock).open() and verify(mock).write(data) each ask a single question: did this call happen? Mockito records invocations in order, but plain verification never consults that order, so the pair passes for either sequence. For ordering you create an InOrder handle over the mocks you care about and verify through it: InOrder inOrder = inOrder(resource); inOrder.verify(resource).open(); inOrder.verify(resource).write(data); The handle keeps a cursor into the recorded invocation list. Each inOrder.verify searches forward from the cursor for a matching call and moves the cursor past it; if the match is only found before the cursor, the verification fails. It also works across several mocks: pass them all to inOrder(a, b). Two details worth saying: the handle must be verified through (a plain static verify is order-blind even while an InOrder exists), and the check is a subsequence check, not an exact-transcript check — unverified calls in between are allowed.
code
java · 9 linesInOrder inOrder = inOrder(resource);
inOrder.verify(resource).open();
inOrder.verify(resource).write(data);
inOrder.verify(resource).close();
InOrder tx = inOrder(txManager, repository);
tx.verify(txManager).begin();
tx.verify(repository).save(entity);
tx.verify(txManager).commit();go deeper
Show the three lines (create handle, verify, verify) and state clearly that plain verify ignores order.
Explain the forward-moving cursor, cross-mock handles, and that unverified calls in between are tolerated.
Add failure semantics (VerificationInOrderFailure), the static-verify pitfall, and when ordering is contract versus over-specification.
Frame ordering assertions as an interaction-contract decision: assert only orders whose violation is a real defect, to keep tests from ossifying implementation detail.
## What Mockito records and what plain verify asks Every mock keeps an ordered list of the invocations it received. A plain verify(mock).open() runs a matcher over that whole list and asserts the number of matches (once, by default). Position never enters into it. So a test with verify(resource).open(); verify(resource).write(data); passes whether the production code opened then wrote, or wrote then opened — which is exactly the bug such a test is often written to prevent. ## The InOrder handle Mockito.inOrder(Object... mocks) returns an InOrder object that carries a shared verification cursor across the mocks you pass in. Verifications performed through that handle are position-aware: InOrder inOrder = inOrder(resource); inOrder.verify(resource).open(); inOrder.verify(resource).write(data); inOrder.verify(resource).close(); Each call scans forward from the current cursor for the first invocation matching the wanted method and arguments. On success the cursor advances past that invocation, so subsequent verifications can only match later calls. If no match exists at or after the cursor — for instance because write happened before open — Mockito fails with a VerificationInOrderFailure saying the wanted invocation was not found in order (often with a 'Wanted ... but was ...' comparison). ## Rules people trip over Only verifications made through the handle are ordered. Mixing in a plain Mockito.verify(resource).write(data) adds an unordered assertion and does not move the cursor. Only mocks passed to inOrder() participate; verifying a mock that was not passed in is a misuse error, and interactions with mocks outside the handle are invisible to it. Argument matchers work exactly as in normal verification, so inOrder.verify(resource).write(argThat(...)) is fine, and a call with different arguments simply does not match. ## Ordering across collaborators The same handle spans mocks, which is how you assert cross-object protocols: InOrder inOrder = inOrder(txManager, repository); inOrder.verify(txManager).begin(); inOrder.verify(repository).save(entity); inOrder.verify(txManager).commit(); This is a genuine strength of InOrder — it verifies the interleaving of two objects, which no per-mock assertion can express. ## It is a subsequence, not a transcript InOrder asserts relative order of the calls you verify, and tolerates any other calls before, between or after them. That keeps the test from breaking when unrelated interactions are added, but it also means the test is not asserting 'these and only these calls, in this order'. To tighten it you add inOrder.verifyNoMoreInteractions() or a separate exact-count verification. ## When to reach for it Ordering assertions are valuable when the order is part of the contract: lock before mutate, begin before save before commit, validate before persist, write header before body, close after flush. They are over-specification when the order is an incidental implementation choice — asserting it then makes a harmless refactor fail. A useful habit is to write ordinary verifications by default and reach for InOrder only when you can name the bug that reordering would cause.
- What happens if you call the static Mockito.verify() instead of inOrder.verify() while an InOrder handle exists?You get a normal, order-blind verification: it asserts the call happened but ignores position and does not advance the handle's cursor. The test then silently loses the ordering guarantee it appears to make, which is why every assertion that is meant to be ordered must go through the handle.
- Can you verify order for a mock you did not pass to inOrder()?No. Mockito raises a misuse error telling you the mock is not part of the in-order verification. The handle only tracks the mocks it was given, and interactions with any other mock are simply invisible to it, so all participants in the protocol must be listed when the handle is created.
Plain verify is checking a guest list — did these people attend? InOrder is checking the CCTV timeline — did this one walk in before that one?
saying these in an interview costs you the question
- Believing consecutive plain verify() calls already assert order
- Creating an InOrder handle but then verifying statically
- Thinking the order of verify statements affects a plain verification
- Expecting an error when extra unverified calls happen between the verified ones
- Assuming a separate InOrder per mock can express cross-mock ordering