@InjectMocks annotation in JUnit - Build an Automation Script
import static org.mockito.Mockito.*; import static org.junit.jupiter.api.Assertions.*; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; @ExtendWith(MockitoExtension.class) public class UserServiceTest { @Mock UserRepository userRepository; @InjectMocks UserService userService; @Test void testGetUserNameReturnsStubbedName() { // Arrange: stub repository method when(userRepository.findUserNameById(1)).thenReturn("Alice"); // Act: call service method String result = userService.getUserName(1); // Assert: verify returned value assertEquals("Alice", result); // Verify repository method was called once verify(userRepository, times(1)).findUserNameById(1); } } // Supporting classes interface UserRepository { String findUserNameById(int id); } class UserService { private final UserRepository userRepository; public UserService(UserRepository userRepository) { this.userRepository = userRepository; } public String getUserName(int id) { return userRepository.findUserNameById(id); } }
This test class uses @ExtendWith(MockitoExtension.class) to enable Mockito annotations.
The @Mock annotation creates a mock instance of UserRepository.
The @InjectMocks annotation creates an instance of UserService and injects the mocked UserRepository into it.
In the test method, we stub the repository method findUserNameById to return "Alice" when called with 1.
We then call the service method getUserName and assert it returns "Alice".
Finally, we verify that the repository method was called exactly once.
This setup ensures the service is tested in isolation with controlled dependencies.
Now add data-driven testing with 3 different user IDs and expected names
Practice
@InjectMocks annotation in JUnit testing?Solution
Step 1: Understand the role of @InjectMocks
@InjectMocks creates an instance of the class under test and injects mocks into it automatically.Step 2: Compare with other annotations
@Mock creates mock objects, but does not inject them. @Spy wraps real objects. @InjectMocks handles injection.Final Answer:
To create the class under test and inject mock dependencies automatically -> Option BQuick Check:
@InjectMocks = auto-inject mocks [OK]
- Confusing @InjectMocks with @Mock
- Thinking @InjectMocks creates mocks instead of injecting
- Assuming @InjectMocks runs tests or manages threads
@InjectMocks in a JUnit 5 test class?Solution
Step 1: Check field declaration syntax
Fields with @InjectMocks should be private and declared without manual instantiation.Step 2: Identify correct syntax
@InjectMocks private Service service; declares a private field with @InjectMocks without manual instantiation, letting the framework create it.Final Answer:
@InjectMocks private Service service; -> Option AQuick Check:
Private field + no manual new = correct [OK]
- Manually instantiating the field defeats @InjectMocks purpose
- Using package-private or public fields without private
- Missing semicolon or incorrect syntax
service.process() if dependency.doWork() is mocked to return "mocked"?class Dependency {
String doWork() { return "real"; }
}
class Service {
Dependency dependency;
String process() { return dependency.doWork(); }
}
@InjectMocks
Service service;
@Mock
Dependency dependency;
@BeforeEach
void setup() {
MockitoAnnotations.openMocks(this);
when(dependency.doWork()).thenReturn("mocked");
}
@Test
void testProcess() {
System.out.println(service.process());
}Solution
Step 1: Understand @InjectMocks and @Mock interaction
@InjectMocks creates Service and injects the mocked Dependency instance into it.Step 2: Analyze method call and mock behavior
dependency.doWork() is mocked to return "mocked", so service.process() returns "mocked".Final Answer:
"mocked" -> Option DQuick Check:
Mocked method returns "mocked" [OK]
- Expecting real method output instead of mocked
- Forgetting to initialize mocks with openMocks
- Assuming dependency is null causing NullPointerException
@InjectMocks
Service service;
@Mock
Dependency dependency;
@BeforeEach
void setup() {
MockitoAnnotations.openMocks(this);
}
@Test
void test() {
System.out.println(service.process());
}When running the test, a
NullPointerException occurs at service.process(). What is the most likely cause?Solution
Step 1: Identify cause of NullPointerException
NullPointerException at service.process() means dependency inside Service is null.Step 2: Check injection of mocks
@InjectMocks should inject mocks into Service fields, but if Service's dependency field is not properly declared or missing setter, injection fails.Final Answer:
The dependency field in Service is not initialized or injected -> Option CQuick Check:
NullPointerException = missing injection [OK]
- Assuming missing @Mock causes NPE (it causes different errors)
- Thinking openMocks call is missing when it is present
- Confusing @InjectMocks placement with injection failure
OrderService that depends on PaymentService and InventoryService. You want to write a JUnit test using @InjectMocks to inject mocks of both dependencies. Which setup correctly uses @InjectMocks and @Mock to achieve this?Solution
Step 1: Identify the class under test
OrderService is the class under test, so it should be annotated with @InjectMocks.Step 2: Identify dependencies to mock
PaymentService and InventoryService are dependencies, so they should be annotated with @Mock.Step 3: Check for manual instantiation
OrderService should not be manually instantiated when using @InjectMocks to allow automatic injection.Final Answer:
@InjectMocks OrderService orderService; @Mock PaymentService paymentService; @Mock InventoryService inventoryService; -> Option AQuick Check:
Class under test @InjectMocks + dependencies @Mock [OK]
- Annotating dependencies with @InjectMocks instead of @Mock
- Manually instantiating class under test with @InjectMocks
- Annotating class under test with @Mock instead of @InjectMocks
Ready to prove it?
Pass the test and this pattern moves unknown
