To use @Mock and @InjectMocks with JUnit, you typically use them with Mockito.
@Mockcreates a fake/mock dependency.@InjectMockscreates the class under test and injects the mocks into it.- With JUnit 5, you enable Mockito using
@ExtendWith(MockitoExtension.class).
1. Add Mockito dependencies
Maven
<dependencies>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<version>5.11.4</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-junit-jupiter</artifactId>
<version>5.14.2</version>
<scope>test</scope>
</dependency>
</dependencies>
Gradle
dependencies {
testImplementation 'org.junit.jupiter:junit-jupiter:5.11.4'
testImplementation 'org.mockito:mockito-junit-jupiter:5.14.2'
}
test {
useJUnitPlatform()
}
2. Example class to test
Suppose you have a service that depends on a repository:
public class UserService {
private final UserRepository userRepository;
public UserService(UserRepository userRepository) {
this.userRepository = userRepository;
}
public String getUsernameById(Long id) {
User user = userRepository.findById(id);
if (user == null) {
return "Unknown";
}
return user.getName();
}
}
Repository:
public interface UserRepository {
User findById(Long id);
}
Model:
public class User {
private final Long id;
private final String name;
public User(Long id, String name) {
this.id = id;
this.name = name;
}
public Long getId() {
return id;
}
public String getName() {
return name;
}
}
3. Use @Mock and @InjectMocks
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;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.Mockito.when;
@ExtendWith(MockitoExtension.class)
class UserServiceTest {
@Mock
private UserRepository userRepository;
@InjectMocks
private UserService userService;
@Test
void getUsernameByIdReturnsUserNameWhenUserExists() {
when(userRepository.findById(1L))
.thenReturn(new User(1L, "Alice"));
String result = userService.getUsernameById(1L);
assertEquals("Alice", result);
}
@Test
void getUsernameByIdReturnsUnknownWhenUserDoesNotExist() {
when(userRepository.findById(99L))
.thenReturn(null);
String result = userService.getUsernameById(99L);
assertEquals("Unknown", result);
}
}
How it works
@Mock
private UserRepository userRepository;
This tells Mockito to create a mock implementation of UserRepository.
@InjectMocks
private UserService userService;
This tells Mockito to create a UserService instance and inject the mocked UserRepository into it.
Mockito tries injection in this order:
- Constructor injection
- Setter injection
- Field injection
Constructor injection is usually the best option because it makes dependencies explicit and easier to test.
Verifying mock interactions
You can also verify that a dependency method was called:
import static org.mockito.Mockito.verify;
@Test
void getUsernameByIdCallsRepository() {
when(userRepository.findById(1L))
.thenReturn(new User(1L, "Alice"));
userService.getUsernameById(1L);
verify(userRepository).findById(1L);
}
Common mistake: forgetting Mockito extension
If you forget this:
@ExtendWith(MockitoExtension.class)
then your @Mock fields may remain null, causing a NullPointerException.
JUnit 4 version
If you are using JUnit 4, use @RunWith(MockitoJUnitRunner.class) instead:
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;
import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.when;
@RunWith(MockitoJUnitRunner.class)
public class UserServiceTest {
@Mock
private UserRepository userRepository;
@InjectMocks
private UserService userService;
@Test
public void getUsernameByIdReturnsUserNameWhenUserExists() {
when(userRepository.findById(1L))
.thenReturn(new User(1L, "Alice"));
String result = userService.getUsernameById(1L);
assertEquals("Alice", result);
}
}
Quick summary
Use this pattern for JUnit 5:
@ExtendWith(MockitoExtension.class)
class MyServiceTest {
@Mock
private MyRepository repository;
@InjectMocks
private MyService service;
@Test
void testSomething() {
when(repository.findSomething()).thenReturn("value");
String result = service.doSomething();
assertEquals("value", result);
}
}
Use @Mock for dependencies and @InjectMocks for the class you are testing.
