The @InjectMocks annotation helps automatically create and inject mock objects into the class you want to test. It saves time and makes tests cleaner.
@InjectMocks annotation in JUnit
@InjectMocks private ClassToTest classToTest;
This annotation is used together with @Mock or @Spy annotations.
Mockito will create an instance of ClassToTest and inject mocks into it.
Dependency and injects it into Service automatically.@Mock private Dependency dependency; @InjectMocks private Service service;
Helper and injects it into Controller.@Spy private Helper helper; @InjectMocks private Controller controller;
This test uses @InjectMocks to create a Calculator instance with a mocked Adder. The test checks that the add method returns the mocked value.
import static org.mockito.Mockito.*; import org.junit.jupiter.api.Test; import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.MockitoAnnotations; class Calculator { private Adder adder; public Calculator(Adder adder) { this.adder = adder; } public int add(int a, int b) { return adder.add(a, b); } } interface Adder { int add(int x, int y); } public class CalculatorTest { @Mock Adder adder; @InjectMocks Calculator calculator; public CalculatorTest() { MockitoAnnotations.openMocks(this); } @Test void testAdd() { when(adder.add(2, 3)).thenReturn(5); int result = calculator.add(2, 3); assert result == 5 : "Expected 5 but got " + result; System.out.println("Test passed: " + (result == 5)); } }
Always initialize mocks with MockitoAnnotations.openMocks(this) or use @ExtendWith(MockitoExtension.class) in JUnit 5.
@InjectMocks tries to inject mocks by constructor, setter, or field injection in that order.
@InjectMocks creates the class under test and injects mocks automatically.
It reduces manual setup and keeps tests clean.
Works well with @Mock and @Spy annotations.
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
