How to Use @InjectMocks Annotation in JUnit Tests
Use the
@InjectMocks annotation in JUnit with Mockito to create an instance of the class under test and automatically inject its @Mock dependencies. This simplifies setup by letting Mockito handle dependency injection for your test objects.Syntax
The @InjectMocks annotation is placed on the class instance you want to test. Mockito will create this instance and inject all fields annotated with @Mock or @Spy into it.
Typical usage:
@Mock: Creates mock objects for dependencies.@InjectMocks: Creates the class under test and injects mocks into it.
java
public class MyServiceTest { @Mock private Dependency dependency; @InjectMocks private MyService myService; // tests here }
Example
This example shows how @InjectMocks automatically injects a mocked dependency into the service class for testing.
java
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 private UserRepository userRepository; @InjectMocks private UserService userService; @Test void testGetUserName() { when(userRepository.findNameById(1)).thenReturn("Alice"); String name = userService.getUserName(1); assertEquals("Alice", name); verify(userRepository).findNameById(1); } } class UserService { private final UserRepository userRepository; public UserService(UserRepository userRepository) { this.userRepository = userRepository; } public String getUserName(int id) { return userRepository.findNameById(id); } } interface UserRepository { String findNameById(int id); }
Output
Test passed successfully
Common Pitfalls
- Not initializing mocks with
@ExtendWith(MockitoExtension.class)orMockitoAnnotations.openMocks(this)causes@InjectMocksto fail. - Using
@InjectMockswithout any@Mockdependencies results in a real instance with null dependencies. - Constructor injection is preferred; if multiple constructors exist, Mockito may fail to inject mocks correctly.
- Fields not mocked or not visible (private without setters) won't be injected.
java
/* Wrong: Missing Mockito initialization */ public class WrongTest { @Mock Dependency dep; @InjectMocks Service service; // service will be null or have null dependencies @Test void test() { // test fails due to null pointer } } /* Right: Use MockitoExtension to initialize mocks */ import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.junit.jupiter.MockitoExtension; @ExtendWith(MockitoExtension.class) public class RightTest { @Mock Dependency dep; @InjectMocks Service service; // properly injected @Test void test() { // test runs fine } }
Quick Reference
| Annotation | Purpose |
|---|---|
| @Mock | Creates a mock object for a dependency |
| @InjectMocks | Creates the class under test and injects mocks into it |
| @ExtendWith(MockitoExtension.class) | Initializes mocks and injects before tests run |
| MockitoAnnotations.openMocks(this) | Alternative to initialize mocks in setup method |
Key Takeaways
Use @InjectMocks to create the class under test and inject its @Mock dependencies automatically.
Always initialize mocks with @ExtendWith(MockitoExtension.class) or MockitoAnnotations.openMocks(this).
Constructor injection is preferred for reliable mock injection with @InjectMocks.
Without proper initialization, @InjectMocks will not inject mocks and cause NullPointerExceptions.
Use @Mock to create mock dependencies that @InjectMocks will inject into the tested class.