Introduction
The @Spy
annotation in Mockito is used to create a spy instance of a real object. Spies allow you to perform partial mocking, where some methods of the object are mocked while others retain their original behavior. This is particularly useful when you want to test a class with some real method calls and some mocked method calls. In this tutorial, we will demonstrate step by step how to use the @Spy
annotation in Mockito.
Maven Dependencies
To use Mockito with JUnit 5, add the following dependencies to your pom.xml
file:
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>4.8.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-junit-jupiter</artifactId>
<version>4.8.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<version>5.9.2</version>
<scope>test</scope>
</dependency>
Example Scenario
We will create a Calculator
class with methods for addition and subtraction. Our goal is to test the Calculator
methods using Mockito's @Spy
annotation, where we will partially mock the subtraction method while keeping the addition method real.
Calculator Class
First, create the Calculator
class.
public class Calculator {
public int add(int a, int b) {
return a + b;
}
public int subtract(int a, int b) {
return a - b;
}
}
JUnit 5 Test Class with Mockito
Create a test class for Calculator
using JUnit 5 and Mockito.
import static org.mockito.Mockito.*;
import static org.junit.jupiter.api.Assertions.*;
import org.junit.jupiter.api.Test;
import org.mockito.Spy;
import org.mockito.junit.jupiter.MockitoExtension;
import org.junit.jupiter.api.extension.ExtendWith;
@ExtendWith(MockitoExtension.class)
public class CalculatorTest {
@Spy
private Calculator calculator;
@Test
public void testAdd() {
// Given
// No need to mock the add method, we want to use the real method
// When
int result = calculator.add(10, 20);
// Then
assertEquals(30, result);
}
@Test
public void testSubtract() {
// Given
doReturn(5).when(calculator).subtract(10, 5);
// When
int result = calculator.subtract(10, 5);
// Then
assertEquals(5, result);
verify(calculator).subtract(10, 5);
}
@Test
public void testSubtractRealMethod() {
// Given
// No stubbing for subtract, so the real method will be called
// When
int result = calculator.subtract(10, 5);
// Then
assertEquals(5, result);
}
}
Explanation
Annotations:
@ExtendWith(MockitoExtension.class)
: Integrates Mockito with JUnit 5, enabling the use of Mockito annotations.@Spy
: Creates a spy instance of theCalculator
class.
testAdd():
- Given: No need to mock the
add
method because we want to use the real method. - When: Calls the
add
method on theCalculator
instance. - Then: Asserts that the result is 30.
- Given: No need to mock the
testSubtract():
- Given: Uses
doReturn(5).when(calculator).subtract(10, 5);
to mock thesubtract
method. - When: Calls the
subtract
method on theCalculator
instance. - Then: Asserts that the result is 5 and verifies that the
subtract
method was called with the arguments 10 and 5.
- Given: Uses
testSubtractRealMethod():
- Given: No stubbing for the
subtract
method, so the real method will be called. - When: Calls the
subtract
method on theCalculator
instance. - Then: Asserts that the result is 5, confirming that the real method was executed.
- Given: No stubbing for the
Additional Scenario
Scenario: Combining Real and Mocked Methods
In this scenario, we will demonstrate how to combine real and mocked methods in a single test.
@Test
public void testAddAndSubtract() {
// Given
doReturn(3).when(calculator).subtract(7, 4);
// When
int additionResult = calculator.add(2, 3);
int subtractionResult = calculator.subtract(7, 4);
// Then
assertEquals(5, additionResult); // Real method
assertEquals(3, subtractionResult); // Mocked method
}
Explanation
- Given: Uses
doReturn(3).when(calculator).subtract(7, 4);
to mock thesubtract
method. - When: Calls both the
add
andsubtract
methods on theCalculator
instance. - Then: Asserts that the result of the addition (real method) is 5 and the result of the subtraction (mocked method) is 3.
Conclusion
The @Spy
annotation in Mockito allows you to create spies, enabling partial mocking of real objects. By using @Spy
, you can keep the real behavior of some methods while mocking others, providing flexibility in your unit tests. This step-by-step guide demonstrated how to effectively use the @Spy
annotation in your unit tests, covering different scenarios to ensure comprehensive testing of the Calculator
class.
Comments
Post a Comment
Leave Comment