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.mockitomockito-core5.14.2testorg.mockitomockito-junit-jupiter5.14.2test
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.
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
Mock-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 default
Unused 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.MockitoSession
Programmatic 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.
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.
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.