Introduction
In this chapter, we will learn about stubbing methods with argument matchers using Mockito. Argument matchers allow you to define flexible stubs that can match a range of arguments, making your tests more versatile and easier to write.
What is Stubbing?
Stubbing is the process of specifying what mock objects should do when their methods are called. By defining the behavior of mock objects, you can control their interactions and ensure that your tests are reliable and predictable. Stubbing allows you to return specific values, throw exceptions, or execute custom logic when a method is called.
Stubbing with Argument Matchers
Argument matchers allow you to stub methods with flexible arguments. This is useful when you want to specify behavior for a range of inputs without having to define stubs for each specific set of arguments.
Example: Calculator Class and CalculatorTest Class
Class Under Test: Calculator
public class Calculator {
public int add(int a, int b) {
return a + b;
}
public int subtract(int a, int b) {
return a - b;
}
public int multiply(int a, int b) {
return a * b;
}
public int divide(int a, int b) {
if (b == 0) {
throw new IllegalArgumentException("Division by zero");
}
return a / b;
}
}
Test Class: CalculatorTest
import static org.mockito.Mockito.*;
import static org.mockito.ArgumentMatchers.*;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;
public class CalculatorTest {
@Test
void testStubbingWithAnyInt() {
// Create a mock object of Calculator
Calculator calculator = mock(Calculator.class);
// Stub the add method with argument matchers
when(calculator.add(anyInt(), anyInt())).thenReturn(10);
// Use the mock object
int result1 = calculator.add(4, 6);
int result2 = calculator.add(7, 3);
// Assert the results
assertEquals(10, result1);
assertEquals(10, result2);
// Verify the interactions
verify(calculator).add(4, 6);
verify(calculator).add(7, 3);
}
@Test
void testStubbingWithSpecificArgumentMatchers() {
// Create a mock object of Calculator
Calculator calculator = mock(Calculator.class);
// Stub the divide method with specific argument matchers
when(calculator.divide(anyInt(), eq(2))).thenReturn(5);
// Use the mock object
int result1 = calculator.divide(10, 2);
int result2 = calculator.divide(20, 2);
// Assert the results
assertEquals(5, result1);
assertEquals(5, result2);
// Verify the interactions
verify(calculator).divide(10, 2);
verify(calculator).divide(20, 2);
}
}
Explanation
- Creating a Mock:
Calculator calculator = mock(Calculator.class);
This line creates a mock object of the
Calculator
class. - Stubbing with Argument Matchers:
when(calculator.add(anyInt(), anyInt())).thenReturn(10);
This line defines the behavior of the
add
method. When theadd
method is called with any integer arguments, it will return10
. - Using the Mock Object:
int result1 = calculator.add(4, 6); int result2 = calculator.add(7, 3);
These lines call the
add
method on the mock object with different arguments and store the results. - Asserting the Results:
assertEquals(10, result1); assertEquals(10, result2);
These lines check if the results are as expected.
- Verifying Interactions:
verify(calculator).add(4, 6); verify(calculator).add(7, 3);
These lines verify that the
add
method was called with the specified arguments. - Stubbing with Specific Argument Matchers:
when(calculator.divide(anyInt(), eq(2))).thenReturn(5);
This line defines the behavior of the
divide
method. When thedivide
method is called with any integer as the first argument and2
as the second argument, it will return5
. - Using the Mock Object for Division:
int result1 = calculator.divide(10, 2); int result2 = calculator.divide(20, 2);
These lines call the
divide
method on the mock object with different arguments and store the results. - Asserting the Division Results:
assertEquals(5, result1); assertEquals(5, result2);
These lines check if the results are as expected.
- Verifying Division Interactions:
verify(calculator).divide(10, 2); verify(calculator).divide(20, 2);
These lines verify that the
divide
method was called with the specified arguments.
Running Tests using IntelliJ IDEA
Conclusion
Stubbing methods with argument matchers using Mockito allows you to create flexible and versatile tests. By using argument matchers like anyInt()
and eq()
, you can define stubs that handle a wide range of inputs, making your tests more robust and easier to maintain. This approach helps you validate the behavior of your code under various conditions, ensuring that it performs correctly in different scenarios.