DS DevShelfHub Projects · AI tools
Cheatsheets / Mockito
Cheatsheet · Dev tooling

Mockito Cheatsheet: Mock, Stub, Verify and Capture Reference

By DevShelfHub

mock, spy, stub, verify, ArgumentCaptor, MockedStatic, MockedConstruction, BDD, @InjectMocks — the Java mocking library as a one-page reference.

115 items 8 min Mock Verify Capture

Start hereQuick start · 6 you’ll reach for daily

Make a mockmock(UserRepo.class)
Stub returnwhen(m.x()).thenReturn(v)
Stub throwwhen(m.x()).thenThrow(E.class)
Verifyverify(m).x(any())
Capture argArgumentCaptor.forClass(...)
Spy realspy(new ArrayList<>())

Target versions · paceVersions

Targets: mockito-core ≥ 5.14 java ≥ 11 junit-jupiter ≥ 5.11

Mockito 5 makes the inline mock maker the default — meaning final classes, static methods, and constructors can now be mocked without the extra mockito-inline artifact. JDK 8 support was dropped. The fluent API lives under Mockito.* (stubbing + verification) and ArgumentMatchers.* (any/eq/argThat). For BDD style, use BDDMockito.given(...).willReturn(...).

Install · wireSetup

bash


  org.mockito
  mockito-core
  5.14.2
  test


  org.mockito
  mockito-junit-jupiter     
  5.14.2
  test






dependencies {
    testImplementation("org.mockito:mockito-core:5.14.2")
    testImplementation("org.mockito:mockito-junit-jupiter:5.14.2")
}

# Use a static import for the fluent API
import static org.mockito.Mockito.*;
import static org.mockito.ArgumentMatchers.*;

# JUnit 5 wiring
@ExtendWith(MockitoExtension.class)
class UserServiceTest {
    @Mock UserRepo repo;                          // populated automatically
    @InjectMocks UserService svc;                 // constructed with the mocks
}

# Or manual init (one-liner, JUnit 4 / no extension)
@BeforeEach void init() { MockitoAnnotations.openMocks(this); }

mock · spy · @InjectMocksCreating mocks

UserRepo m = mock(UserRepo.class);Empty mock — every method returns the type’s default (null, 0, empty).
UserRepo m = mock(UserRepo.class, "repo");Named mock — helpful in error messages.
mock(UserRepo.class, withSettings().lenient())Stop strict-stubbing complaints for this mock.
List<String> s = spy(new ArrayList<>());Real object, partially mockable. Use doReturn() for stubs.
@Mock UserRepo repo;Field-level mock — needs MockitoExtension or openMocks().
@Spy UserRepo repo = new InMemoryRepo();Spy with explicit init.
@InjectMocks UserService svc;Preferred Wire mocks into constructor / field of SUT.
@Captor ArgumentCaptor<User> cap;Field-level captor — matched by name.
MockitoAnnotations.openMocks(this)Manual init — close the returned AutoCloseable to free resources.
Mockito 5 default mock-maker is mockito-inline. That lets you mock final classes, static methods, and constructors without an extra dependency. If you were pinning mockito-inline explicitly, you can drop it.

when().thenReturn / doX().when()Stubbing

when(repo.find(1L)).thenReturn(user)Stub a return value.
when(repo.find(1L)).thenReturn(a).thenReturn(b)Stage values — last one repeats.
when(repo.find(1L)).thenThrow(NotFoundException.class)Throw on call.
when(repo.save(any())).thenAnswer(inv -> inv.getArgument(0))Compute the answer — echo args, build dynamic values.
when(repo.find(any())).thenCallRealMethod()Delegate to the real impl (use on spies, or partial mocks).
doReturn(v).when(spy).get(0)For spies Avoids running the real method during stubbing.
doThrow(new IOException()).when(repo).flush()Stub a void method.
doNothing().when(repo).reset()Make a void no-op even after the default. Useful with a spy.
doAnswer(inv -> { ...; return null; }).when(...)...Side-effect with a custom answer.
RETURNS_DEFAULTS / RETURNS_SMART_NULLS / RETURNS_DEEP_STUBS / RETURNS_MOCKSDefault-answer strategies for unstubbed calls.
reset(mock)Avoid Wipes stubs + interactions. Usually a sign the test is doing too much.
javascript
import static org.mockito.Mockito.*;
import static org.mockito.ArgumentMatchers.*;

UserRepo repo = mock(UserRepo.class);

// 1. Simple stub
when(repo.findById(1L)).thenReturn(new User(1, "alice"));

// 2. Stage multiple returns — last one repeats
when(repo.next())
    .thenReturn(1)
    .thenReturn(2)
    .thenThrow(new IllegalStateException("drained"));

// 3. Throw on call
when(repo.findById(-1L)).thenThrow(NotFoundException.class);

// 4. Compute the answer (Answer)
when(repo.save(any())).thenAnswer(inv -> {
    User u = inv.getArgument(0);
    return u.withId(42L);                           // echo back with id
});

// 5. Void methods — use doX() forms
doThrow(new IOException()).when(repo).flush();
doNothing().when(repo).reset();
doAnswer(inv -> { log("called"); return null; }).when(repo).reset();

// 6. Spy (real object, can override per method) — doReturn() avoids running the real method
List spy = spy(new ArrayList<>());
doReturn("X").when(spy).get(0);                   // safe even when get(0) would throw

// 7. Default-return for unstubbed methods
UserRepo deep = mock(UserRepo.class, RETURNS_DEEP_STUBS);
when(deep.find().byEmail("a")).thenReturn(...);   // chained
UserRepo smart = mock(UserRepo.class, RETURNS_SMART_NULLS);  // safer null than NPE

any · eq · argThatArgument matchers

All or none. Once one argument uses a matcher, every argument in that call must — wrap literals in eq(...).

any() / any(Class)Any value (incl. null) / any non-null of type.
anyString() / anyInt() / anyLong() / anyBoolean() / anyDouble()Primitive-safe shortcuts — never match null.
anyList() / anyMap() / anyCollection() / anyIterable()Type-narrowed any.
eq(value)Equality — required when other args use matchers.
same(ref) / refEq(obj, "ignoredField")Reference identity / reflection-based equality.
argThat(u -> u.id() == 1)Custom predicate — lambda form.
isNull() / notNull() / isNotNull()Null checks.
startsWith(s) / endsWith(s) / contains(s) / matches(regex)String helpers.
intThat(n -> n > 0) / longThat / doubleThatPrimitive-friendly argThat.
aryEq(new int[]{1,2})Array equality (element-wise).

verify · times · inOrderVerification

verify(mock).method(args)Default: exactly one matching call.
verify(mock, times(n)).method(...)Exactly N calls.
verify(mock, never()).method(...)Asserts the call did not happen.
verify(mock, atLeast(n) | atLeastOnce() | atMost(n) | only())Count constraints. only() = exactly one + nothing else.
verify(mock, timeout(500)).method(...)Wait up to 500ms for the call (async / threaded code).
verify(mock, after(500)).method(...)Wait 500ms then assert — for "should still equal 1 in half a second".
verifyNoMoreInteractions(mock)After all verify()s, fail if anything else happened.
verifyNoInteractions(mock)Mock was never touched.
InOrder o = inOrder(a, b); o.verify(a).x(); o.verify(b).y();Cross-mock ordering check.
verify(mock).should(...)BDDMockito-style alias (works after then(mock).should()).
javascript
import static org.mockito.Mockito.*;
import static org.mockito.ArgumentMatchers.*;

// 1. Verify a call happened (default = exactly once)
verify(repo).save(any(User.class));

// 2. Counts
verify(repo, times(2)).save(any());
verify(repo, never()).delete(any());
verify(repo, atLeast(1)).find(anyLong());
verify(repo, atMost(3)).find(anyLong());
verify(repo, atLeastOnce()).save(any());

// 3. Mixed: assert no further interactions
verify(repo).save(any());
verifyNoMoreInteractions(repo);                    // every call must have been verified
verifyNoInteractions(emailer);                     // nothing touched this mock

// 4. Order across mocks
InOrder order = inOrder(repo, audit);
order.verify(repo).save(any());
order.verify(audit).log(eq("user.created"));

// 5. Capture args for richer assertions
ArgumentCaptor userCap = ArgumentCaptor.forClass(User.class);
verify(repo).save(userCap.capture());
assertEquals("alice", userCap.getValue().name());

// Multi-arg capture in one go
ArgumentCaptor msg = ArgumentCaptor.forClass(String.class);
verify(audit, times(2)).log(msg.capture());
assertThat(msg.getAllValues()).containsExactly("user.created", "user.welcome");

// Or with @Captor on a field
// @Captor ArgumentCaptor cap;

grab the args after the factArgumentCaptor

ArgumentCaptor<User> cap = ArgumentCaptor.forClass(User.class)Build a captor.
verify(repo).save(cap.capture())Capture the actual argument during verification.
cap.getValue() / cap.getAllValues()Last call / every captured call.
@Captor ArgumentCaptor<User> capField form — needs MockitoExtension.
ArgumentCaptor.forClass(List.class).captures(any())Generic-type erasure: cast yourself or use @Captor which preserves it.
Prefer captors for rich assertions, matchers for control flow. Matchers (argThat(...)) decide whether the stub fires; captors let you assert "what was the email?" with the full power of your assertion library.

mockStatic · mockConstructionStatic, constructor & final

try (MockedStatic<Math> m = mockStatic(Math.class)) { m.when(() -> Math.abs(-1)).thenReturn(42); ... }Stub a static method only inside the try block.
m.verify(() -> Math.abs(-1))Verify the static was called.
try (MockedConstruction<UUID> mc = mockConstruction(UUID.class)) { new UUID(0,0); ... }Every new UUID(...) inside the scope yields a mock.
mc.constructed()List of mocks created — one per new.
mockConstruction(C.class, (mock, ctx) -> when(mock.x()).thenReturn(v))Initialise each constructed mock with stubs.
final classes / methodsMock-able in Mockito 5 default. No mockito-inline needed.
Static + construction mocks are scoped to the try-with-resources block. Leak the MockedStatic across tests and you’ll watch unrelated tests fail mysteriously. Always declare inside the test, always close.

given · when · thenBDDMockito

import static org.mockito.BDDMockito.*;BDD aliases over the same engine.
given(repo.find(1L)).willReturn(user)Stub. Reads as given the repo returns user when called with 1.
given(repo.flush()).willThrow(IOException.class)Throw form.
willDoNothing().given(repo).reset()Void method form.
then(repo).should().save(any())Verify in BDD style.
then(repo).should(times(2)).save(any())With a verification mode.
then(repo).shouldHaveNoInteractions()Equivalent to verifyNoInteractions.

unused stubs · lenientStrictness & settings

MockitoExtension is STRICT_STUBS by defaultUnused stubs → UnnecessaryStubbingException. Argument mismatches are flagged.
@MockitoSettings(strictness = Strictness.LENIENT)Relax for a class — mostly for shared @BeforeEach stubs.
lenient().when(repo.find(any())).thenReturn(user)Per-stub opt-out. Better than blanket lenient.
withSettings().name("repo").verboseLogging()Log every interaction. Debug-only.
withSettings().defaultAnswer(RETURNS_SMART_NULLS)Pick a default answer for this mock.
withSettings().stubOnly()No interaction recording — lighter memory for huge mocks.
org.mockito.MockitoSessionProgrammatic strict-stubbing if you can’t use the JUnit extension.

Service + collaboratorsEnd-to-end · Checkout service

Three collaborators wired with @InjectMocks, happy path with captor + InOrder, and a failure path asserting rollback. Mockito + JUnit 5 + JUnit assertions in one tight class.

javascript
import static org.mockito.Mockito.*;
import static org.mockito.ArgumentMatchers.*;
import static org.junit.jupiter.api.Assertions.*;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.*;
import org.mockito.junit.jupiter.MockitoExtension;

@ExtendWith(MockitoExtension.class)
class CheckoutServiceTest {

    @Mock  PaymentGateway gateway;
    @Mock  InventoryRepo  inventory;
    @Mock  AuditLog       audit;
    @InjectMocks CheckoutService svc;             // ctor: (gateway, inventory, audit)

    @Captor ArgumentCaptor chargeCap;

    @Test
    void chargesAndAuditsOnSuccess() {
        when(inventory.reserve(eq("sku-1"), anyInt())).thenReturn(true);
        when(gateway.charge(any())).thenReturn(Result.ok("ch_1"));

        var receipt = svc.checkout(new Cart("sku-1", 2), "u-1");

        assertEquals("ch_1", receipt.chargeId());

        verify(inventory).reserve("sku-1", 2);
        verify(gateway).charge(chargeCap.capture());
        assertEquals(2 * 9_99, chargeCap.getValue().amountCents());

        InOrder order = inOrder(inventory, gateway, audit);
        order.verify(inventory).reserve(any(), anyInt());
        order.verify(gateway).charge(any());
        order.verify(audit).log("checkout.success", "u-1");
        verifyNoMoreInteractions(audit);
    }

    @Test
    void rollsBackWhenChargeFails() {
        when(inventory.reserve(any(), anyInt())).thenReturn(true);
        when(gateway.charge(any())).thenThrow(new GatewayException("declined"));

        assertThrows(GatewayException.class, () -> svc.checkout(new Cart("sku-1", 1), "u-1"));

        verify(inventory).release("sku-1", 1);    // rollback ran
        verify(audit).log("checkout.failure", "u-1");
    }
}

Best practiceGood to know

Default to strict stubbing. MockitoExtension catches unused stubs and arg-mismatch typos — the cheapest dead-code linter you’ll ever get. Only relax it per-stub when you have a real reason.
Use doReturn().when() on spies. when(spy.x()).thenReturn(v) actually calls the real x() first to set up the stub — which can throw or mutate state. doReturn sidesteps that.
Constructor injection beats @InjectMocks field digging. @InjectMocks is convenient but silently leaves nulls if a collaborator type doesn’t match. A single-constructor SUT is unambiguous.

Common trapsWatch out for

Mixing matchers and literals. verify(repo).save("alice", any()) throws InvalidUseOfMatchersException. Once you use one matcher, wrap every arg — literals in eq("alice").
when() doesn’t work on void methods. Use doThrow / doAnswer / doNothing().when(mock).voidMethod() instead.
Static / construction mocks aren’t global. They’re tied to the calling thread + the try-with-resources scope. Submitting work to another thread bypasses them entirely.

Go deeperSee also

Mockito FAQ

What is Mockito used for?

Mockito is the most popular Java mocking framework. It lets you replace real dependencies with test doubles (mocks and spies) so you can unit test a class in isolation, stub return values, verify interactions, and capture arguments — all without a running database or external service.

What is the difference between a mock and a spy in Mockito?

A mock is a synthetic object with all methods stubbed to return defaults (null, 0, false) unless you override them with when(). A spy wraps a real object and delegates unstubbed calls to the real implementation. Use mocks for full isolation; use spies when you want to test the real behavior of most methods but override one or two.

How does when().thenReturn() work in Mockito?

when(mock.method(args)).thenReturn(value) registers a stubbing: whenever method() is called with matching args, return value instead of the default. Chain thenReturn calls for consecutive invocations. Use thenThrow(Exception.class) to simulate exceptions. Argument matchers like any(), eq(), and argThat() give flexible matching.

What is ArgumentCaptor used for?

ArgumentCaptor lets you capture the actual argument passed to a mocked method and inspect it in assertions. Create with ArgumentCaptor.forClass(MyClass.class), pass capture() to verify(), then call getValue() or getAllValues(). It is useful when you cannot use eq() matchers because the argument is constructed inside the method under test.

How do I mock static methods and constructors in Mockito?

Use MockedStatic in a try-with-resources block: try (MockedStatic<MyClass> m = mockStatic(MyClass.class)) { m.when(MyClass::staticMethod).thenReturn(val); }. For constructors, use MockedConstruction: mockConstruction(MyClass.class, (mock, ctx) -> when(mock.x()).thenReturn(val)). Both require mockito-inline (included in Mockito 5).

Is Mockito free and open source?

Yes. Mockito is MIT-licensed and free. Add it as a test-scope dependency in Maven or Gradle — mockito-core for most use cases, mockito-junit-jupiter for the JUnit 5 extension. No licence or subscription is needed.