Introduction
In this chapter, we will learn about verifying interactions in Mockito. Verifying interactions is a crucial part of unit testing, as it ensures that your code interacts with its dependencies in the expected manner. This helps confirm that your code is working correctly and adheres to the intended logic.
What is Verifying Interactions?
Verifying interactions involves checking if certain methods were called on mock objects during the test. It allows you to ensure that your code interacts with its dependencies as expected, such as calling methods with the correct arguments, the correct number of times, and in the correct order.
Verifying Method Calls
Mockito provides various ways to verify that methods were called on a mock object. You can verify the number of times a method was called, check if it was called with specific arguments, or verify the order of method calls.
Example: UserService Class and UserServiceTest Class
Class Under Test: UserService
public class UserService {
private UserRepository userRepository;
private EmailService emailService;
public UserService(UserRepository userRepository, EmailService emailService) {
this.userRepository = userRepository;
this.emailService = emailService;
}
public void registerUser(User user) {
userRepository.save(user);
emailService.sendWelcomeEmail(user.getEmail());
}
}
Supporting Classes: UserRepository and EmailService
public class UserRepository {
public void save(User user) {
// Save the user to the database
}
}
public class EmailService {
public void sendWelcomeEmail(String email) {
// Send a welcome email
}
}
User Class
public class User {
private String email;
public User(String email) {
this.email = email;
}
public String getEmail() {
return email;
}
}
Test Class: UserServiceTest
import static org.mockito.Mockito.*;
import org.junit.jupiter.api.Test;
public class UserServiceTest {
@Test
void testRegisterUser_VerifyMethodCalls() {
// Create mock objects for UserRepository and EmailService
UserRepository userRepository = mock(UserRepository.class);
EmailService emailService = mock(EmailService.class);
// Create an instance of UserService with the mock dependencies
UserService userService = new UserService(userRepository, emailService);
// Create a user
User user = new User("test@example.com");
// Register the user
userService.registerUser(user);
// Verify that the save method was called with the correct user
verify(userRepository).save(user);
// Verify that the sendWelcomeEmail method was called with the correct email
verify(emailService).sendWelcomeEmail("test@example.com");
}
}
Explanation
- Creating Mocks:
UserRepository userRepository = mock(UserRepository.class); EmailService emailService = mock(EmailService.class);
These lines create mock objects of the
UserRepository
andEmailService
classes. - Creating an Instance of UserService:
UserService userService = new UserService(userRepository, emailService);
This line creates an instance of the
UserService
class with the mock dependencies. - Creating a User:
User user = new User("test@example.com");
This line creates a
User
object with an email address. - Registering the User:
userService.registerUser(user);
This line calls the
registerUser
method on theUserService
instance with the createdUser
object. - Verifying Method Calls:
verify(userRepository).save(user); verify(emailService).sendWelcomeEmail("test@example.com");
These lines verify that the
save
method ofUserRepository
and thesendWelcomeEmail
method ofEmailService
were called with the correct arguments.
Output
Verifying Number of Method Calls
You can also verify the number of times a method was called using times()
, never()
, atLeast()
, and atMost()
.
Example: Verifying Number of Calls
@Test
void testRegisterUser_VerifyNumberOfCalls() {
// Create mock objects for UserRepository and EmailService
UserRepository userRepository = mock(UserRepository.class);
EmailService emailService = mock(EmailService.class);
// Create an instance of UserService with the mock dependencies
UserService userService = new UserService(userRepository, emailService);
// Create a user
User user = new User("test@example.com");
// Register the user twice
userService.registerUser(user);
userService.registerUser(user);
// Verify that the save method was called twice with the correct user
verify(userRepository, times(2)).save(user);
// Verify that the sendWelcomeEmail method was called twice with the correct email
verify(emailService, times(2)).sendWelcomeEmail("test@example.com");
}
Explanation
- Verifying Method Call Count:
verify(userRepository, times(2)).save(user); verify(emailService, times(2)).sendWelcomeEmail("test@example.com");
These lines verify that the
save
andsendWelcomeEmail
methods were each called twice with the correct arguments.
Verifying No Interactions
You can verify that no interactions have occurred with a mock using verifyNoInteractions()
or that no further interactions have occurred using verifyNoMoreInteractions()
.
Example: Verifying No Interactions
@Test
void testNoInteractions() {
// Create mock objects for UserRepository and EmailService
UserRepository userRepository = mock(UserRepository.class);
EmailService emailService = mock(EmailService.class);
// Verify that no interactions have occurred
verifyNoInteractions(userRepository, emailService);
}
Example: Verifying No More Interactions
@Test
void testNoMoreInteractions() {
// Create mock objects for UserRepository and EmailService
UserRepository userRepository = mock(UserRepository.class);
EmailService emailService = mock(EmailService.class);
// Create an instance of UserService with the mock dependencies
UserService userService = new UserService(userRepository, emailService);
// Create a user
User user = new User("test@example.com");
// Register the user
userService.registerUser(user);
// Verify interactions
verify(userRepository).save(user);
verify(emailService).sendWelcomeEmail("test@example.com");
// Verify that no more interactions have occurred
verifyNoMoreInteractions(userRepository, emailService);
}
Explanation
- Verifying No Interactions:
verifyNoInteractions(userRepository, emailService);
This line verifies that no interactions have occurred with the
userRepository
andemailService
mocks. - Verifying No More Interactions:
verifyNoMoreInteractions(userRepository, emailService);
This line verifies that no further interactions have occurred with the
userRepository
andemailService
mocks beyond what has already been verified.
Verifying Order of Interactions
You can verify the order of interactions using InOrder
.
Example: Verifying Order of Interactions
@Test
void testVerifyOrderOfInteractions() {
// Create mock objects for UserRepository and EmailService
UserRepository userRepository = mock(UserRepository.class);
EmailService emailService = mock(EmailService.class);
// Create an instance of UserService with the mock dependencies
UserService userService = new UserService(userRepository, emailService);
// Create a user
User user = new User("test@example.com");
// Register the user
userService.registerUser(user);
// Verify the order of interactions
InOrder inOrder = inOrder(userRepository, emailService);
inOrder.verify(userRepository).save(user);
inOrder.verify(emailService).sendWelcomeEmail("test@example.com");
}
Explanation
- Verifying Order of Interactions:
InOrder inOrder = inOrder(userRepository, emailService); inOrder.verify(userRepository).save(user); inOrder.verify(emailService).sendWelcomeEmail("test@example.com");
These lines verify that the
save
method was called onuserRepository
before thesendWelcomeEmail
method was called onemailService
.
Conclusion
Verifying interactions in Mockito ensures that your methods interact with their dependencies as expected. By using methods like verify()
, verifyNoInteractions()
, verifyNoMoreInteractions()
, and InOrder
, you can check if methods were called with the correct arguments, the correct number of times, and in the correct order. This helps confirm that your code is functioning correctly and adhering to the intended logic. Verifying interactions is a crucial part of writing effective and reliable unit tests.