skip to content

In Mockito's BDD API, how do you assert that a collaborator was called a given number of times, never called, or called in a specific order, and how do those forms map to verify(...)?

level: middleimportance: should knowfreq 30%

answer

  1. then(mock).should(mode).call()
  2. mode goes inside should(...)
  3. shouldHaveNoInteractions / NoMoreInteractions
  4. InOrder object passed into should(...)
  5. AssertJ also has a static then(...)

basics

~10 s

Use then(mock).should(times(2)).save(order), then(mock).should(never()).charge(any()), then(mock).shouldHaveNoInteractions() and then(mock).shouldHaveNoMoreInteractions(). Ordering passes an InOrder object: then(mock).should(inOrder).lock(id). These are exact renamings of verify(mock, times(2)), verify(mock, never()) and verifyNoInteractions.

solid answer

~30 s

`then(mock).should()` is the BDD spelling of `verify(mock)`. The verification mode goes inside `should(...)`, exactly where it goes as `verify`'s second argument: - `then(repo).should().save(order)` maps to `verify(repo).save(order)` - `then(repo).should(times(2)).save(order)` maps to `verify(repo, times(2)).save(order)` - `then(gateway).should(never()).charge(any())` maps to `verify(gateway, never())` - `atLeastOnce()`, `atMost(3)`, `only()`, `timeout(100)` work identically The mock-level checks have their own names: `then(mock).shouldHaveNoInteractions()` for `verifyNoInteractions(mock)`, and `then(mock).shouldHaveNoMoreInteractions()` for `verifyNoMoreInteractions(mock)`. Ordering uses the same `InOrder` object as classic Mockito: build `InOrder inOrder = inOrder(lockService, repo)`, then `then(lockService).should(inOrder).lock(id)` followed by `then(repo).should(inOrder).save(order)`. As on the stubbing side, nothing behaves differently — modes, matcher rules and failure messages are the same.

code

java · 10 lines
java
InOrder inOrder = inOrder(lockService, repository);

service.settle(orderId);

then(lockService).should(inOrder).lock(orderId);
then(repository).should(inOrder).save(any(Order.class));

then(repository).should(times(2)).save(any(Order.class));
then(gateway).should(never()).charge(any());
then(auditLog).shouldHaveNoInteractions();

go deeper

for a junior

Recall the shape then(mock).should().call() and that the mode goes inside should, mapping directly to verify with its second argument.

for a middle

Cover times/never/atLeastOnce/only, the two no-interactions forms, and InOrder passed into should.

for a senior

Add the asynchronous modes and their difference, plus the judgement about which interactions deserve verification at all.

for a principal

Speak to convention and maintainability: exhaustive interaction checks raise refactoring cost, so standardise where verification is appropriate rather than how it is spelled.

## The core mapping Verification in BDD style starts with `then(mock)` and continues with `should(...)`, where the argument is the same `VerificationMode` you would pass to `verify` as its second parameter. | classic | BDD | |---|---| | `verify(mock).call()` | `then(mock).should().call()` | | `verify(mock, times(3)).call()` | `then(mock).should(times(3)).call()` | | `verify(mock, never()).call()` | `then(mock).should(never()).call()` | | `verify(mock, atLeastOnce()).call()` | `then(mock).should(atLeastOnce()).call()` | | `verify(mock, atMost(2)).call()` | `then(mock).should(atMost(2)).call()` | | `verify(mock, only()).call()` | `then(mock).should(only()).call()` | | `verify(mock, timeout(100)).call()` | `then(mock).should(timeout(100)).call()` | | `verifyNoInteractions(mock)` | `then(mock).shouldHaveNoInteractions()` | | `verifyNoMoreInteractions(mock)` | `then(mock).shouldHaveNoMoreInteractions()` | | `verify(mock, inOrderObj).call()` | `then(mock).should(inOrderObj).call()` | Everything else is unchanged: argument matchers, the all-or-none matcher rule, `ArgumentCaptor`, and the wording of failure messages, which still speak of "Wanted but not invoked" and list the actual interactions. ## Reading the modes correctly `times(n)` means exactly n matching calls — not at least n. `never()` is `times(0)`. `atLeastOnce()` and `atLeast(n)` set a floor; `atMost(n)` a ceiling. `only()` asserts that the verified call is the *only* interaction that mock received, which is stricter than it looks and breaks as soon as another call is added. `timeout(ms)` is for asynchronous code: it polls until the expected interaction arrives or the deadline passes, and combines with counts as `should(timeout(200).times(2))`. Note the difference from `after(ms)`, which always waits the full period — use `after` when asserting that something did *not* happen within a window, and `timeout` when you want to return as soon as it does. ## Ordering `InOrder` is created with `inOrder(mockA, mockB)` and passed into `should(...)`. It verifies relative order among the calls you check on the mocks it was created with; unverified calls in between are ignored. For exhaustiveness there is still the classic `inOrder.verifyNoMoreInteractions()`, since the `then(...)` chain offers no separate name for it. ## Where verification belongs Style aside, the same discipline applies as with classic verification: verify interactions that *are* the observable outcome and have no return value to assert — an event published, a mail sent, a payment charged — or the deliberate absence of one, which `should(never())` states clearly. Verifying every call turns the test into a transcript of the implementation and makes refactoring fail it. `shouldHaveNoMoreInteractions()` deserves particular restraint: it asserts nothing else at all touched the mock, so adding a metric or a lookup breaks unrelated tests. It earns its place only when "nothing else happened" is genuinely part of the contract. ## Practical pointers The verification call comes after the action, so a BDD test reads: `given(...)` for setup, a bare call for the action, then `then(...).should(...)` and value assertions. A frequent stumble is forgetting the empty `should()` for the simple case — `then(mock).save(order)` does not compile, because `then(mock)` returns a verification object, not the mock. Another is name collision: AssertJ also exposes a static `then(...)` in `BDDAssertions` for assertions. Static-importing both in one class makes the compiler resolve by argument type, which usually works but reads ambiguously; teams typically import one and qualify the other.

  • What is the difference between then(mock).shouldHaveNoInteractions() and then(mock).shouldHaveNoMoreInteractions()?
    The first asserts the mock was never touched at all during the test. The second asserts that beyond the interactions you already verified, nothing else happened. The second should be used sparingly, because any newly added call, even a harmless read or metric, fails tests that were never about it.
  • How do you verify an interaction that happens asynchronously?
    Wrap the mode in timeout, for example then(publisher).should(timeout(500)).publish(event), which polls until the interaction occurs or the deadline expires. To assert that something does not happen within a window, use after(500) with never(), since after always waits the full period rather than returning early.

saying these in an interview costs you the question

  • Writing then(mock).save(order) without should(), expecting it to compile
  • Reading times(2) as 'at least twice' instead of exactly twice
  • Using only() casually and being surprised when an unrelated added call fails the test
  • Confusing shouldHaveNoInteractions with shouldHaveNoMoreInteractions
  • Expecting after(ms) to return as soon as the interaction happens, like timeout(ms)

context