Module 18: Testing, Delivery, and Runtime Operations
Mocking with Mockito
Use Mockito to isolate collaborators when a true unit test needs control over dependencies, while avoiding over-mocking and fake complexity. You will learn what to stub, what to verify, and when a real collaborator is a better choice.
Author
Java Learner Editorial Team
Reviewer
Technical review by Java Learner
Last reviewed
2026-04-17
Java version
Java 25 LTS
Learning goals
- Mock collaborators at the unit boundary without turning tests into implementation scripts
- Use stubbing and verification for the right reasons
- Avoid mocking simple values, collections, or domain objects that are cheaper to create for real
Before you start
- You are comfortable building multi-class Java applications and reading project structure
Lesson roadmap: Start with the mental model, then follow the design choices, common pitfalls, and the practical workflow you should apply in a real project.
Mocks are useful when a class depends on collaborators you do not want to call for real in a unit test: Payment gateways, repositories, or external clients are common examples.
Mockito helps you stub responses and verify interactions: That lets you focus on the class under test instead of pulling in the whole system.
Do not mock everything automatically: If the test mostly verifies your own stubs, it is no longer testing useful behavior.
Practical rule: Mock slow, external, or unstable collaborators. Keep real logic real when that makes the test more meaningful.
Why mocking exists: A unit test sometimes needs to replace a slow, random, remote, or stateful collaborator so the test can focus on one class’s behavior.
Stubbing vs verification: Stubbing controls what the dependency returns. Verification checks whether the dependency interaction happened. Both are useful, but either can be overused if the test starts mirroring every line of production code.
Mock boundaries, not data: Most value objects, collections, and simple domain entities are easier to create directly than to mock. Mocks are best for collaborators with behavior, not for plain data holders.
Design signal: If a test needs five mocks just to call one method, the production class may own too many responsibilities.
How to study this module: Treat every tool here as part of one delivery pipeline. Tests, builds, containers, and CI are not separate checkboxes; together they decide whether other people can trust your code.
Code review mindset: Good engineering workflow reduces risk. Reviewers look for repeatable builds, focused tests, useful failure messages, and deploy steps that are automated rather than tribal knowledge.
Production habit: Make the safe path the default path. The easier it is to run tests, build images, and verify changes, the more often the team will actually do it.
Runnable examples
Verify that one collaborator was called
verify(emailService).sendWelcomeEmail("ada@example.com");Expected output
The test confirms the dependency interaction happened as expected.
Stub a collaborator and assert the service result
when(emailGateway.send("hello")).thenReturn(true);
assertTrue(notificationService.notify("hello"));Expected output
The unit test controls the collaborator so it can focus on the service behavior.
Common mistakes
Verifying every internal call in a class under test
Verify interactions only when they are part of the observable contract or essential side effect.
Mocking simple domain objects that are easier to construct directly
Prefer real objects for plain data and reserve mocks for behavior-heavy collaborators.
Mini exercise
Pick one service class that depends on a repository and an email gateway. Write down which dependency you would mock in a pure unit test, what value you would stub, and one interaction you might verify.
Summary
- Mocks isolate the class under test from external collaborators.
- Mockito can stub responses and verify interactions.
- Too much mocking produces brittle, low-value tests.
- Mockito is most useful at collaboration boundaries, not everywhere.
- Too much mocking often signals that the production class is doing too much.
Next step
Now manage project dependencies and repeatable builds with Maven or Gradle.
Sources used