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
-
Creating Mocks:
InventoryService inventoryService = mock(InventoryService.class);
This line creates a mock object of the
InventoryService
class. -
Stubbing Method:
when(inventoryService.isInStock(anyString())).thenReturn(true);
This line stubs the
isInStock
method of theInventoryService
mock to returntrue
when called with any string. -
Creating an Instance of ShoppingCartService:
ShoppingCartService shoppingCartService = new ShoppingCartService(inventoryService);
This line creates an instance of the
ShoppingCartService
class with the mock dependency. -
Adding Items to the Cart:
shoppingCartService.addItemToCart("product123", 2); shoppingCartService.addItemToCart("product123", 3);
These lines call the
addItemToCart
method on theShoppingCartService
instance with the specified arguments. -
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. -
Checking Out the Cart:
shoppingCartService.checkoutCart("product123", 2);
This line calls the
checkoutCart
method on theShoppingCartService
instance with the specified arguments. -
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
anddeductStock
methods were each called once with the specified arguments. -
Verifying Minimum Invocation Count:
verify(inventoryService, atLeast(2)).reserveProduct("product123", 2); verify(inventoryService, atLeast(2)).deductStock("product123", 2);
These lines verify that the
reserveProduct
anddeductStock
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
- 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.