Difference between @Mock and @InjectMocks
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
In Mockito, @Mock and @InjectMocks serve different roles in a unit test. @Mock creates a test double for a dependency, while @InjectMocks creates the object under test and tries to inject the available mocks into it.
@Mock Creates a Mocked Dependency
Use @Mock on collaborators whose behavior you want to control.
That field is not a real PaymentGateway. It is a Mockito-generated mock that returns default values until you stub it.
The whole point of @Mock is to isolate the unit under test from real external behavior.
@InjectMocks Creates the Subject Under Test
@InjectMocks is applied to the class you actually want to test.
Mockito will create CheckoutService and try to inject the available mocks into it using constructor injection first, then setter or field injection if needed.
That means service is usually a real object with mocked dependencies, not a mock itself.
See the Difference in a Full Example
Here:
- '
gatewayis a mock' - '
repositoryis a mock' - '
serviceis the real class under test, constructed with those mocks'
That is the mental model you want to keep.
@InjectMocks Does Not Replace Good Test Design
Mockito injection is convenient, but it should not hide the class structure. If a service has too many dependencies, @InjectMocks may make the test compile while still leaving the design overly coupled.
In those cases, the annotation is not the problem. The object under test probably has too many responsibilities.
Prefer Constructor Injection in Production Code
Mockito works best when the production class uses constructor injection. That makes dependencies explicit and usually leads Mockito to inject them predictably.
Field injection can still work, but constructor-based design is clearer and easier to reason about in both production and test code.
Avoid Confusing @InjectMocks with @Spy
A frequent mistake is thinking @InjectMocks makes a partially mocked object. It does not. If you need a real object with some method interception, that is a different concept, usually involving @Spy.
@InjectMocks is about wiring dependencies, not about changing the nature of the subject under test.
Once that distinction is clear, test setup becomes much easier to read: mocks stand in for collaborators, while the injected object is the thing whose logic you are actually asserting.
That separation is the core reason Mockito provides both annotations instead of one generic test helper.
Common Pitfalls
- Assuming
@InjectMockscreates a mock instead of a real object with injected mocks. - Forgetting that
@Mockobjects need stubbing when default Mockito return values are not enough. - Using
@InjectMocksto hide an over-coupled class with too many dependencies. - Relying on field injection patterns that make dependency wiring less explicit.
- Confusing
@InjectMockswith@Spyor other Mockito annotations.
Summary
- '
@Mockcreates mocked dependencies.' - '
@InjectMockscreates the subject under test and injects mocks into it.' - The class marked with
@InjectMocksis usually a real object, not a mock. - Constructor injection makes Mockito wiring clearer and more reliable.
- These annotations help test structure, but they do not fix poor class design.

