skip to content

Inside an ordered Mockito verification, what does the calls(2) mode do that neither times(2) nor atLeast(2) does, and when would you reach for it?

level: seniorimportance: nice to knowfreq 15%

answer

  1. calls(n) = non-greedy, InOrder only
  2. times(n) fails on the extra call
  3. atLeast(n) consumes everything
  4. leaves surplus unverified for later
  5. pairs with inOrder.verifyNoMoreInteractions

basics

~20 s

calls(n) is the non-greedy ordered mode: it consumes exactly n consecutive matching calls and moves on, tolerating further calls of the same method afterwards without marking them verified. times(n) fails if more matching calls follow in range, and atLeast(n) greedily consumes all of them.

solid answer

~50 s

calls(n) exists only for ordered verification — it is rejected outside an InOrder handle. Suppose a mock receives poll() three times and you care that two polls happened at this point in the protocol, without asserting the total. inOrder.verify(mock, calls(2)).poll() matches two consecutive invocations, advances the cursor past them, and leaves the third unverified and available for later ordered verifications. Compare: inOrder.verify(mock, times(2)).poll() is greedy about the count — it insists the matching run is exactly two and fails on a third; inOrder.verify(mock, atLeast(2)).poll() succeeds but consumes all matching invocations, so a following ordered verification cannot see them and inOrder.verifyNoMoreInteractions() will not complain about them. Reach for calls(n) when a protocol has repeated steps of unknown or irrelevant multiplicity and you need to keep verifying what comes after them — for example 'at least these two writes, then a flush'.

code

java · 8 lines
java
client.poll(); client.poll(); client.poll();
client.flush();
client.close();

InOrder inOrder = inOrder(client);
inOrder.verify(client, calls(2)).poll(); // consumes 2, third stays unverified
inOrder.verify(client).flush();
inOrder.verify(client).close();

go deeper

for a junior

Not expected; at most recognise that ordered verification has extra modes beyond times().

for a middle

State the non-greedy definition and contrast it with times(n) failing on the extra call.

for a senior

Explain cursor consumption, why atLeast is greedy, the InOrder-only restriction, and a concrete protocol test where it matters.

for a principal

Discuss how consumption semantics shape what a following no-more-interactions assertion can still catch, and when count assertions are over-specification.

## The problem calls(n) solves Ordered verification is cursor-based: each verification consumes some invocations and moves the cursor. That makes the consumption policy of each mode observable, which is where the three modes differ. times(n) in an ordered context asserts that the matching run starting at the cursor has exactly n elements; a further matching call in that run makes it fail. That is what you want when the count is part of the contract, but it makes the test brittle if the number of repetitions is incidental. atLeast(n) passes with n or more, but it is greedy: it marks all the matching invocations it finds as verified and pushes the cursor past them. The count assertion is loose, yet the side effect on the cursor is total — you cannot then verify a later occurrence of the same call separately, and those invocations no longer count as unverified for an ordered no-more-interactions check. calls(n) is the non-greedy middle: exactly n consecutive matching invocations are consumed from the cursor, no upper bound is asserted, and anything beyond them stays unverified and reachable. Mockito's own documentation states it will not fail if the method was called three times (unlike times(2)) and will not mark the third invocation as verified (unlike atLeast(2)). ## Ordered-only by design calls(n) is meaningless without a cursor — 'the next n calls' has no referent in unordered verification — so Mockito rejects it outside an InOrder handle. This is one of several mode restrictions in ordered verification: modes that do not implement the in-order contract, such as atMost, are refused with an error saying that mode is not implemented to work with InOrder. Knowing which modes are legal where is a common senior-level detail. ## A worked shape A batching client polls a queue an unspecified number of times, then flushes, then closes. The contract worth asserting is 'at least two polls happened before the flush, and close came after the flush', not the exact poll count, which depends on batch size and timing. InOrder inOrder = inOrder(client); inOrder.verify(client, calls(2)).poll(); inOrder.verify(client).flush(); inOrder.verify(client).close(); With times(2) this fails whenever the client polls a third time before flushing. With atLeast(2) it passes, but the greedy consumption swallows every poll, including any that occur after the flush — so a stray post-flush poll would go unnoticed by a subsequent ordered check. ## Interaction with verifyNoMoreInteractions Because calls(n) leaves surplus invocations unverified, following it with inOrder.verifyNoMoreInteractions() will fail if any of those surplus calls occurred after the last verified one. That combination is a precise way to say 'exactly this protocol shape, with these repeated steps, and nothing trailing'. With atLeast(n) the same combination is silently weaker, since the extra calls were already marked verified. ## When not to use it If the repetition count is genuinely part of the contract, assert it with times(n) and let a third call fail the test. If neither the count nor the position matters, do not use an ordered mode at all — a plain atLeast(1) is clearer. calls(n) earns its place only when you need to step over a variable-length run and continue verifying the sequence after it, which is a narrow but real situation in protocol-style tests.

  • Why does Mockito refuse calls(n) outside an InOrder handle?
    The mode is defined relative to a verification cursor — it means 'the next n matching invocations from the current position'. Unordered verification has no position, so the phrase has no meaning and any implementation would silently degrade into times(n) or atLeast(n). Mockito raises a misuse error rather than pick one.

saying these in an interview costs you the question

  • Believing calls(n) works in ordinary, unordered verification
  • Thinking calls(2) fails when the method was called three times
  • Assuming atLeast(2) leaves the extra invocations unverified
  • Treating calls(n) as a synonym for times(n) inside InOrder
  • Expecting atMost(n) to be usable inside an InOrder verification

context