Introduction
In this chapter, we will learn about verifying behavior in Mockito. Verifying behavior is a key aspect of testing with Mockito, as it allows you to ensure that your methods interact with their dependencies as expected. This helps you confirm that your code is functioning correctly and adhering to the intended logic.
What is Verifying Behavior?
Verifying behavior is the process of checking whether certain methods were called on mock objects during the test. By using verification, you can ensure that your code interacts with its dependencies in the expected manner, 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: OrderService Class and OrderServiceTest Class
Class Under Test: OrderService
public class OrderService {
private PaymentService paymentService;
private InventoryService inventoryService;
public OrderService(PaymentService paymentService, InventoryService inventoryService) {
this.paymentService = paymentService;
this.inventoryService = inventoryService;
}
public void placeOrder(Order order) {
if (inventoryService.isInStock(order.getProductId())) {
paymentService.processPayment(order.getAmount());
inventoryService.updateStock(order.getProductId());
}
}
}
Supporting Classes: PaymentService and InventoryService
public class PaymentService {
public void processPayment(double amount) {
// Process the payment
}
}
public class InventoryService {
public boolean isInStock(String productId) {
// Check if the product is in stock
return true;
}
public void updateStock(String productId) {
// Update the stock for the product
}
}
Test Class: OrderServiceTest
import static org.mockito.Mockito.*;
import org.junit.jupiter.api.Test;
public class OrderServiceTest {
@Test
void testPlaceOrder_VerifyMethodCalls() {
// Create mock objects for PaymentService and InventoryService
PaymentService paymentService = mock(PaymentService.class);
InventoryService inventoryService = mock(InventoryService.class);
// Stub the isInStock method to return true
when(inventoryService.isInStock(anyString())).thenReturn(true);
// Create an instance of OrderService with the mock dependencies
OrderService orderService = new OrderService(paymentService, inventoryService);
// Create an order
Order order = new Order("product123", 100.0);
// Place the order
orderService.placeOrder(order);
// Verify that the processPayment method was called with the correct amount
verify(paymentService).processPayment(100.0);
// Verify that the isInStock method was called with the correct product ID
verify(inventoryService).isInStock("product123");
// Verify that the updateStock method was called with the correct product ID
verify(inventoryService).updateStock("product123");
}
}
Order Class
public class Order {
private String productId;
private double amount;
public Order(String productId, double amount) {
this.productId = productId;
this.amount = amount;
}
public String getProductId() {
return productId;
}
public double getAmount() {
return amount;
}
}
Explanation
-
Creating Mocks:
PaymentService paymentService = mock(PaymentService.class); InventoryService inventoryService = mock(InventoryService.class);
These lines create mock objects of the
PaymentService
andInventoryService
classes. -
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 OrderService:
OrderService orderService = new OrderService(paymentService, inventoryService);
This line creates an instance of the
OrderService
class with the mock dependencies. -
Creating an Order:
Order order = new Order("product123", 100.0);
This line creates an
Order
object with a product ID and an amount. -
Placing the Order:
orderService.placeOrder(order);
This line calls the
placeOrder
method on theOrderService
instance with the createdOrder
object. -
Verifying Method Calls:
verify(paymentService).processPayment(100.0); verify(inventoryService).isInStock("product123"); verify(inventoryService).updateStock("product123");
These lines verify that the
processPayment
,isInStock
, andupdateStock
methods were called with the correct arguments.
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 testPlaceOrder_VerifyNumberOfCalls() {
// Create mock objects for PaymentService and InventoryService
PaymentService paymentService = mock(PaymentService.class);
InventoryService inventoryService = mock(InventoryService.class);
// Stub the isInStock method to return true
when(inventoryService.isInStock(anyString())).thenReturn(true);
// Create an instance of OrderService with the mock dependencies
OrderService orderService = new OrderService(paymentService, inventoryService);
// Create an order
Order order = new Order("product123", 100.0);
// Place the order twice
orderService.placeOrder(order);
orderService.placeOrder(order);
// Verify that the processPayment method was called twice with the correct amount
verify(paymentService, times(2)).processPayment(100.0);
// Verify that the isInStock method was called twice with the correct product ID
verify(inventoryService, times(2)).isInStock("product123");
// Verify that the updateStock method was called twice with the correct product ID
verify(inventoryService, times(2)).updateStock("product123");
}
Explanation
- Verifying Method Call Count:
verify(paymentService, times(2)).processPayment(100.0); verify(inventoryService, times(2)).isInStock("product123"); verify(inventoryService, times(2)).updateStock("product123");
These lines verify that the
processPayment
,isInStock
, andupdateStock
methods were each called twice with the correct arguments.
Conclusion
Verifying behavior in Mockito allows you to ensure that your methods interact with their dependencies as expected. By using methods like verify()
, times()
, and never()
, you can check if methods were called with the correct arguments and the correct number of times. This helps you confirm that your code is functioning correctly and adhering to the intended logic. Verifying behavior is a crucial part of writing effective and reliable unit tests.