To verify method calls with Mockito and JUnit, use Mockito’s verify() method. This lets you check whether a mocked dependency method was called, how many times it was called, and what arguments were passed.
1. Basic Example
Suppose you have a service that depends on a repository.
public interface UserRepository {
void save(User user);
}
public class UserService {
private final UserRepository userRepository;
public UserService(UserRepository userRepository) {
this.userRepository = userRepository;
}
public void register(User user) {
userRepository.save(user);
}
}
You can verify that save() was called:
import org.junit.jupiter.api.Test;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
class UserServiceTest {
@Test
void register_shouldSaveUser() {
UserRepository userRepository = mock(UserRepository.class);
UserService userService = new UserService(userRepository);
User user = new User();
userService.register(user);
verify(userRepository).save(user);
}
}
The important line is:
verify(userRepository).save(user);
This means: “After running the test, confirm that save(user) was called on userRepository.”
2. Verifying Number of Calls
By default, verify() expects the method to be called exactly once.
These two lines are equivalent:
verify(userRepository).save(user);
verify(userRepository, times(1)).save(user);
You can verify different call counts:
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
verify(userRepository, times(1)).save(user);
verify(userRepository, times(2)).save(user);
verify(userRepository, never()).delete(user);
Common options include:
verify(mock, times(1)).method();
verify(mock, never()).method();
verify(mock, atLeastOnce()).method();
verify(mock, atLeast(2)).method();
verify(mock, atMost(3)).method();
Example:
import org.junit.jupiter.api.Test;
import static org.mockito.Mockito.atLeastOnce;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
class NotificationServiceTest {
@Test
void sendWelcomeEmail_shouldNotifyUser() {
EmailSender emailSender = mock(EmailSender.class);
NotificationService notificationService = new NotificationService(emailSender);
notificationService.sendWelcomeEmail("[email protected]");
verify(emailSender, atLeastOnce()).send("[email protected]", "Welcome!");
}
}
3. Verifying Arguments with Matchers
If you do not want to match the exact object, you can use argument matchers.
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.verify;
verify(userRepository).save(any(User.class));
For specific values:
verify(emailSender).send(eq("[email protected]"), eq("Welcome!"));
You can also mix broad and specific matching:
verify(emailSender).send(eq("[email protected]"), any(String.class));
Important: if you use matchers for one argument, use matchers for all arguments in that method call.
Correct:
verify(emailSender).send(eq("[email protected]"), any(String.class));
Avoid mixing raw values and matchers:
verify(emailSender).send("[email protected]", any(String.class));
4. Verifying No Calls
To verify that a mock had no interactions:
import static org.mockito.Mockito.verifyNoInteractions;
verifyNoInteractions(userRepository);
To verify that no more calls happened after the expected ones:
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
verify(userRepository).save(user);
verifyNoMoreInteractions(userRepository);
Example:
@Test
void register_invalidUser_shouldNotSaveUser() {
UserRepository userRepository = mock(UserRepository.class);
UserService userService = new UserService(userRepository);
User invalidUser = new User();
userService.register(invalidUser);
verifyNoInteractions(userRepository);
}
5. Verifying Order of Calls
Use InOrder when the order matters.
import org.junit.jupiter.api.Test;
import org.mockito.InOrder;
import static org.mockito.Mockito.inOrder;
import static org.mockito.Mockito.mock;
class OrderServiceTest {
@Test
void processOrder_shouldCallMethodsInOrder() {
PaymentService paymentService = mock(PaymentService.class);
InventoryService inventoryService = mock(InventoryService.class);
OrderService orderService = new OrderService(paymentService, inventoryService);
Order order = new Order();
orderService.process(order);
InOrder inOrder = inOrder(inventoryService, paymentService);
inOrder.verify(inventoryService).reserve(order);
inOrder.verify(paymentService).charge(order);
}
}
6. Using @Mock with JUnit 5
Instead of manually creating mocks with mock(), you can use Mockito’s JUnit 5 extension.
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.mockito.Mockito.verify;
@ExtendWith(MockitoExtension.class)
class UserServiceTest {
@Mock
private UserRepository userRepository;
@InjectMocks
private UserService userService;
@Test
void register_shouldSaveUser() {
User user = new User();
userService.register(user);
verify(userRepository).save(user);
}
}
Here:
@Mock
private UserRepository userRepository;
creates a mock repository.
@InjectMocks
private UserService userService;
creates the service and injects the mock into it.
7. Capturing Arguments with ArgumentCaptor
Use ArgumentCaptor when you want to inspect the object passed to a method.
import org.junit.jupiter.api.Test;
import org.mockito.ArgumentCaptor;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
class UserServiceTest {
@Test
void register_shouldSaveUserWithExpectedName() {
UserRepository userRepository = mock(UserRepository.class);
UserService userService = new UserService(userRepository);
userService.register("Alice");
ArgumentCaptor<User> userCaptor = ArgumentCaptor.forClass(User.class);
verify(userRepository).save(userCaptor.capture());
User savedUser = userCaptor.getValue();
assertEquals("Alice", savedUser.getName());
}
}
This is useful when the method under test creates a new object internally, so you cannot verify using the exact same instance.
8. Verifying Exceptions Still Triggers Calls
You can combine JUnit assertions with Mockito verification.
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
class PaymentServiceTest {
@Test
void pay_invalidAmount_shouldLogFailure() {
AuditLogger auditLogger = mock(AuditLogger.class);
PaymentService paymentService = new PaymentService(auditLogger);
assertThrows(IllegalArgumentException.class, () -> {
paymentService.pay(-10);
});
verify(auditLogger).log("Invalid payment amount: -10");
}
}
9. Maven Dependencies
For JUnit 5 and Mockito, add dependencies like these:
<dependencies>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<version>5.13.4</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>5.18.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-junit-jupiter</artifactId>
<version>5.18.0</version>
<scope>test</scope>
</dependency>
</dependencies>
10. Gradle Dependencies
dependencies {
testImplementation 'org.junit.jupiter:junit-jupiter:5.13.4'
testImplementation 'org.mockito:mockito-core:5.18.0'
testImplementation 'org.mockito:mockito-junit-jupiter:5.18.0'
testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
}
test {
useJUnitPlatform()
}
Common Verification Patterns
verify(repository).save(user);
verify(repository, times(1)).save(user);
verify(repository, never()).delete(user);
verify(repository, atLeastOnce()).save(any(User.class));
verify(repository, atMost(3)).findByEmail(any(String.class));
verifyNoInteractions(repository);
verifyNoMoreInteractions(repository);
Summary
Use Mockito’s verify() when you want to test interactions between objects.
Typical usage:
verify(mock).method(argument);
For example:
verify(userRepository).save(user);
Use verification when the important result of a method is not just a returned value, but that another dependency was called correctly.
