Mockito Verifying Invocation Count

Introduction

In this chapter, we will learn about verifying invocation counts using Mockito. Verifying invocation counts allows you to check how many times a method was called on a mock object during a test. This is useful for ensuring that your methods are called the correct number of times, which is crucial for validating the behavior of your code.

What is Verifying Invocation Count?

Verifying invocation count involves checking how many times a specific method was called on a mock object. This helps you ensure that your code interacts with its dependencies the expected number of times.

Example: ShoppingCartService Class and ShoppingCartServiceTest Class

Class Under Test: ShoppingCartService

public class ShoppingCartService {
    private InventoryService inventoryService;

    public ShoppingCartService(InventoryService inventoryService) {
        this.inventoryService = inventoryService;
    }

    public void addItemToCart(String productId, int quantity) {
        if (inventoryService.isInStock(productId)) {
            inventoryService.reserveProduct(productId, quantity);
        }
    }

    public void checkoutCart(String productId, int quantity) {
        if (inventoryService.isInStock(productId)) {
            inventoryService.reserveProduct(productId, quantity);
            inventoryService.deductStock(productId, quantity);
        }
    }
}

Supporting Class: InventoryService

public class InventoryService {
    public boolean isInStock(String productId) {
        // Check if the product is in stock
        return true;
    }

    public void reserveProduct(String productId, int quantity) {
        // Reserve the product
    }

    public void deductStock(String productId, int quantity) {
        // Deduct the product from the stock
    }
}

Test Class: ShoppingCartServiceTest

import static org.mockito.Mockito.*;
import org.junit.jupiter.api.Test;

public class ShoppingCartServiceTest {

    @Test
    void testAddItemToCart_VerifyInvocationCount() {
        // Create a mock object of InventoryService
        InventoryService inventoryService = mock(InventoryService.class);

        // Stub the isInStock method to return true
        when(inventoryService.isInStock(anyString())).thenReturn(true);

        // Create an instance of ShoppingCartService with the mock dependency
        ShoppingCartService shoppingCartService = new ShoppingCartService(inventoryService);

        // Add item to the cart
        shoppingCartService.addItemToCart("product123", 2);
        shoppingCartService.addItemToCart("product123", 3);

        // Verify that the reserveProduct method was called twice with the correct arguments
        verify(inventoryService, times(2)).reserveProduct("product123", 2);
        verify(inventoryService, times(1)).reserveProduct("product123", 3);
    }

    @Test
    void testCheckoutCart_VerifyInvocationCount() {
        // Create a mock object of InventoryService
        InventoryService inventoryService = mock(InventoryService.class);

        // Stub the isInStock method to return true
        when(inventoryService.isInStock(anyString())).thenReturn(true);

        // Create an instance of ShoppingCartService with the mock dependency
        ShoppingCartService shoppingCartService = new ShoppingCartService(inventoryService);

        // Checkout cart
        shoppingCartService.checkoutCart("product123", 2);

        // Verify that the reserveProduct method was called once with the correct arguments
        verify(inventoryService, times(1)).reserveProduct("product123", 2);

        // Verify that the deductStock method was called once with the correct arguments
        verify(inventoryService, times(1)).deductStock("product123", 2);
    }

    @Test
    void testCheckoutCart_VerifyInvocationCount_AtLeast() {
        // Create a mock object of InventoryService
        InventoryService inventoryService = mock(InventoryService.class);

        // Stub the isInStock method to return true
        when(inventoryService.isInStock(anyString())).thenReturn(true);

        // Create an instance of ShoppingCartService with the mock dependency
        ShoppingCartService shoppingCartService = new ShoppingCartService(inventoryService);

        // Checkout cart multiple times
        shoppingCartService.checkoutCart("product123", 2);
        shoppingCartService.checkoutCart("product123", 2);

        // Verify that the reserveProduct method was called at least twice with the correct arguments
        verify(inventoryService, atLeast(2)).reserveProduct("product123", 2);

        // Verify that the deductStock method was called at least twice with the correct arguments
        verify(inventoryService, atLeast(2)).deductStock("product123", 2);
    }
}

Explanation

  1. Creating Mocks:

    InventoryService inventoryService = mock(InventoryService.class);
    

    This line creates a mock object of the InventoryService class.

  2. Stubbing Method:

    when(inventoryService.isInStock(anyString())).thenReturn(true);
    

    This line stubs the isInStock method of the InventoryService mock to return true when called with any string.

  3. Creating an Instance of ShoppingCartService:

    ShoppingCartService shoppingCartService = new ShoppingCartService(inventoryService);
    

    This line creates an instance of the ShoppingCartService class with the mock dependency.

  4. Adding Items to the Cart:

    shoppingCartService.addItemToCart("product123", 2);
    shoppingCartService.addItemToCart("product123", 3);
    

    These lines call the addItemToCart method on the ShoppingCartService instance with the specified arguments.

  5. Verifying Invocation Count for Adding Items:

    verify(inventoryService, times(2)).reserveProduct("product123", 2);
    verify(inventoryService, times(1)).reserveProduct("product123", 3);
    

    These lines verify that the reserveProduct method was called twice with the first set of arguments and once with the second set of arguments.

  6. Checking Out the Cart:

    shoppingCartService.checkoutCart("product123", 2);
    

    This line calls the checkoutCart method on the ShoppingCartService instance with the specified arguments.

  7. Verifying Invocation Count for Checking Out:

    verify(inventoryService, times(1)).reserveProduct("product123", 2);
    verify(inventoryService, times(1)).deductStock("product123", 2);
    

    These lines verify that the reserveProduct and deductStock methods were each called once with the specified arguments.

  8. Verifying Minimum Invocation Count:

    verify(inventoryService, atLeast(2)).reserveProduct("product123", 2);
    verify(inventoryService, atLeast(2)).deductStock("product123", 2);
    

    These lines verify that the reserveProduct and deductStock methods were each called at least twice with the specified arguments.

Verifying No Invocations

You can also verify that a method was never called using never().

Example: Verifying No Invocations

@Test
void testAddItemToCart_VerifyNoInvocations() {
    // Create a mock object of InventoryService
    InventoryService inventoryService = mock(InventoryService.class);

    // Stub the isInStock method to return false
    when(inventoryService.isInStock(anyString())).thenReturn(false);

    // Create an instance of ShoppingCartService with the mock dependency
    ShoppingCartService shoppingCartService = new ShoppingCartService(inventoryService);

    // Add item to the cart
    shoppingCartService.addItemToCart("product123", 2);

    // Verify that the reserveProduct method was never called
    verify(inventoryService, never()).reserveProduct("product123", 2);
}

Explanation

  1. Verifying No Invocations:
    verify(inventoryService, never()).reserveProduct("product123", 2);
    

    This line verifies that the reserveProduct method was never called with the specified arguments.

Conclusion

Verifying invocation counts using Mockito ensures that your methods are called the correct number of times. By using methods like times(), atLeast(), atMost(), and never(), you can check if methods were called the expected number of times, providing better test coverage and validation of your code’s behavior. Verifying invocation counts 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