Mockito Verifying Call Order

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

  1. Creating Mocks:
    AccountService accountService = mock(AccountService.class);
    NotificationService notificationService = mock(NotificationService.class);
    

    These lines create mock objects of the AccountService and NotificationService classes.

  2. Creating an Instance of BankService:
    BankService bankService = new BankService(accountService, notificationService);
    

    This line creates an instance of the BankService class with the mock dependencies.

  3. Performing the Transfer:
    bankService.transferFunds("account1", "account2", 100.0);
    

    This line calls the transferFunds method on the BankService instance to simulate a funds transfer.

  4. 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 on accountService before the credit method, and that the notifyTransfer method on notificationService was called last. This ensures that the methods were called in the correct order.

Running Tests using IntelliJ IDEA

Mockito Verifying Call Order

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

  1. 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 on accountService before the credit method.

  2. 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 and notificationService 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.

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top