Introduction
In this chapter, we will learn about verifying the order of method calls using Mockito. Verifying the call order is crucial for ensuring that methods are called in the expected sequence, which is particularly important in scenarios where the order of operations affects the outcome.
What is Verifying Call Order?
Verifying call order involves checking the sequence in which methods are called on mock objects. This helps ensure that your code interacts with its dependencies in the correct order, maintaining the logical flow of operations.
Example: BankService Class and BankServiceTest Class
Class Under Test: BankService
public class BankService {
private AccountService accountService;
private NotificationService notificationService;
public BankService(AccountService accountService, NotificationService notificationService) {
this.accountService = accountService;
this.notificationService = notificationService;
}
public void transferFunds(String fromAccount, String toAccount, double amount) {
accountService.debit(fromAccount, amount);
accountService.credit(toAccount, amount);
notificationService.notifyTransfer(fromAccount, toAccount, amount);
}
}
Supporting Classes: AccountService and NotificationService
public class AccountService {
public void debit(String account, double amount) {
// Debit the amount from the account
}
public void credit(String account, double amount) {
// Credit the amount to the account
}
}
public class NotificationService {
public void notifyTransfer(String fromAccount, String toAccount, double amount) {
// Notify about the transfer
}
}
Test Class: BankServiceTest
import static org.mockito.Mockito.*;
import org.junit.jupiter.api.Test;
import org.mockito.InOrder;
public class BankServiceTest {
@Test
void testTransferFunds_VerifyCallOrder() {
// Create mock objects for AccountService and NotificationService
AccountService accountService = mock(AccountService.class);
NotificationService notificationService = mock(NotificationService.class);
// Create an instance of BankService with the mock dependencies
BankService bankService = new BankService(accountService, notificationService);
// Perform the transfer
bankService.transferFunds("account1", "account2", 100.0);
// Verify the order of interactions
InOrder inOrder = inOrder(accountService, notificationService);
inOrder.verify(accountService).debit("account1", 100.0);
inOrder.verify(accountService).credit("account2", 100.0);
inOrder.verify(notificationService).notifyTransfer("account1", "account2", 100.0);
}
}
Explanation
- Creating Mocks:
AccountService accountService = mock(AccountService.class); NotificationService notificationService = mock(NotificationService.class);
These lines create mock objects of the
AccountService
andNotificationService
classes. - Creating an Instance of BankService:
BankService bankService = new BankService(accountService, notificationService);
This line creates an instance of the
BankService
class with the mock dependencies. - Performing the Transfer:
bankService.transferFunds("account1", "account2", 100.0);
This line calls the
transferFunds
method on theBankService
instance to simulate a funds transfer. - Verifying the Order of Interactions:
InOrder inOrder = inOrder(accountService, notificationService); inOrder.verify(accountService).debit("account1", 100.0); inOrder.verify(accountService).credit("account2", 100.0); inOrder.verify(notificationService).notifyTransfer("account1", "account2", 100.0);
These lines verify that the
debit
method was called onaccountService
before thecredit
method, and that thenotifyTransfer
method onnotificationService
was called last. This ensures that the methods were called in the correct order.
Running Tests using IntelliJ IDEA
Verifying Order of Multiple Interactions
You can verify the order of multiple interactions on the same mock object or across different mock objects using InOrder
.
Example: Verifying Order of Multiple Interactions
@Test
void testVerifyOrderOfMultipleInteractions() {
// Create mock objects for AccountService and NotificationService
AccountService accountService = mock(AccountService.class);
NotificationService notificationService = mock(NotificationService.class);
// Create an instance of BankService with the mock dependencies
BankService bankService = new BankService(accountService, notificationService);
// Perform the transfer
bankService.transferFunds("account1", "account2", 100.0);
// Verify the order of interactions on the same mock object
InOrder accountServiceInOrder = inOrder(accountService);
accountServiceInOrder.verify(accountService).debit("account1", 100.0);
accountServiceInOrder.verify(accountService).credit("account2", 100.0);
// Verify the order of interactions across different mock objects
InOrder inOrder = inOrder(accountService, notificationService);
inOrder.verify(accountService).debit("account1", 100.0);
inOrder.verify(accountService).credit("account2", 100.0);
inOrder.verify(notificationService).notifyTransfer("account1", "account2", 100.0);
}
Explanation
- Verifying Order of Interactions on the Same Mock Object:
InOrder accountServiceInOrder = inOrder(accountService); accountServiceInOrder.verify(accountService).debit("account1", 100.0); accountServiceInOrder.verify(accountService).credit("account2", 100.0);
These lines verify that the
debit
method was called onaccountService
before thecredit
method. - Verifying Order of Interactions Across Different Mock Objects:
InOrder inOrder = inOrder(accountService, notificationService); inOrder.verify(accountService).debit("account1", 100.0); inOrder.verify(accountService).credit("account2", 100.0); inOrder.verify(notificationService).notifyTransfer("account1", "account2", 100.0);
These lines verify the order of interactions across both the
accountService
andnotificationService
mocks.
Conclusion
Verifying the order of method calls using Mockito ensures that your code interacts with its dependencies in the expected sequence. By using the InOrder
class, you can verify that methods are called in the correct order, ensuring the logical flow of operations. This is particularly useful for testing scenarios where the order of operations affects the outcome. Verifying call order is a crucial part of writing effective and reliable unit tests.