Here’s the scoop on @Mock vs. @InjectMocks in Mockito, and when you reach for each:
@Mock
-
What it does: Creates a dummy instance (a “mock”) of a class or interface. All methods on that mock return default values (null/false/0) until you explicitly stub them.
-
When to use: Anytime your class under test depends on a collaborator you don’t want to exercise for real—e.g., a database client, a web service, a DAO.
java
@Mock
PaymentGateway mockGateway;
This line tells Mockito:
- Construct a fake PaymentGateway object.
- Track every call to its methods.
- Let you stub (when(…).thenReturn(…)) or verify (verify(…)) interactions.
@InjectMocks
-
What it does: Instantiates your class under test and injects all available mocks (and spies) into it. Mockito tries constructor‐injection first, then setter‐injection, then field‐injection.
-
When to use: When you want Mockito to wire your class under test with your @Mock dependencies automatically—so you don’t have to new it yourself or write a DI framework for your unit test.
java
@InjectMocks
OrderService service;
This tells Mockito:
- Find a way to build OrderService (calls its constructor).
- Look at its parameters or fields for types matching your @Mocks (PaymentGateway).
- Plug them in so service.gateway == mockGateway.
Putting it together
java
@ExtendWith(MockitoExtension.class)
class OrderServiceTest {
@Mock // step 1: create mocks
PaymentGateway gateway;
@InjectMocks // step 2: build real OrderService + inject mock
OrderService service;
@Test
void happyPath() {
when(gateway.charge(100)).thenReturn(true); // stub behavior
assertTrue(service.charge(new Order(100))); // exercise & assert
}
}
- @Mock → I need a fake; I’ll define its behavior or verify it later.
- @InjectMocks → I need a real instance of my SUT (Service Under Test) with those fakes wired in.
Best-practice tips
1 One SUT, many mocks
- You usually have one @InjectMocks and several @Mock fields.
2 Limit your mocks
- Mock only outwards-facing dependencies. If a collaborator is a plain data object, don’t mock it.
3 Constructor vs. field injection
- If your class has a single constructor, Mockito uses it. If you have multiple constructors, consider using @InjectMocks on a field + @Mock fields to make it explicit.
4 Avoid mixing frameworks
- Don’t combine Spring’s @Autowired injection with Mockito’s @InjectMocks in the same test—it can get confusing.
When not to use @InjectMocks
-
If you’re doing a pure unit test of a static helper or POJO, you don’t need it—just new the class directly.
-
If you prefer manual wiring for clarity, feel free to call new OrderService(mockGateway) yourself in a @BeforeEach.