Introduction
BDDMockito.willCallRealMethod()
is a method provided by Mockito to support the Behavior-Driven Development (BDD) style of writing tests. It is used to specify that a method call on a mock object should call the real method implementation. This is particularly useful when you want to test the actual behavior of a method while still being able to mock other methods in the same class. This tutorial will demonstrate how to use BDDMockito.willCallRealMethod()
to call real methods in a BDD style.
Maven Dependencies
To use Mockito with JUnit 5 and enable BDDMockito syntax, 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 CalculatorService
class that has a dependency on a MathService
. Our goal is to test the CalculatorService
methods using BDDMockito.willCallRealMethod()
to call the real methods.
CalculatorService and MathService Classes
First, create the MathService
class and the CalculatorService
class.
public class MathService {
public int add(int a, int b) {
return a + b;
}
public int subtract(int a, int b) {
return a - b;
}
}
public class CalculatorService {
private final MathService mathService;
public CalculatorService(MathService mathService) {
this.mathService = mathService;
}
public int addNumbers(int a, int b) {
return mathService.add(a, b);
}
public int subtractNumbers(int a, int b) {
return mathService.subtract(a, b);
}
}
JUnit 5 Test Class with BDDMockito
Create a test class for CalculatorService
using JUnit 5 and BDDMockito
.
import static org.mockito.BDDMockito.*;
import static org.junit.jupiter.api.Assertions.*;
import org.junit.jupiter.api.Test;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import org.junit.jupiter.api.extension.ExtendWith;
@ExtendWith(MockitoExtension.class)
public class CalculatorServiceTest {
@Mock
private MathService mathService;
@InjectMocks
private CalculatorService calculatorService;
@Test
public void testAddNumbersCallsRealMethod() {
// Given
willCallRealMethod().given(mathService).add(anyInt(), anyInt());
// When
int result = calculatorService.addNumbers(5, 3);
// Then
assertEquals(8, result);
then(mathService).should().add(5, 3);
}
@Test
public void testSubtractNumbersCallsRealMethod() {
// Given
willCallRealMethod().given(mathService).subtract(anyInt(), anyInt());
// When
int result = calculatorService.subtractNumbers(10, 4);
// Then
assertEquals(6, result);
then(mathService).should().subtract(10, 4);
}
}
Explanation
Creating Mocks with
@Mock
:- The
@Mock
annotation creates a mock instance of theMathService
class. This mock instance can be used to simulate the behavior of theMathService
in a controlled way.
- The
Injecting Mocks with
@InjectMocks
:- The
@InjectMocks
annotation injects the mockMathService
into theCalculatorService
instance to provide a controlled test environment. This allows theCalculatorService
methods to be tested in isolation from the actualMathService
implementation.
- The
Using BDDMockito:
willCallRealMethod()
: ThewillCallRealMethod().given(mathService).add(anyInt(), anyInt());
method configures the mockMathService
to call the realadd
method when it is called with any integer arguments. This allows theaddNumbers
method of theCalculatorService
class to be tested with the real behavior of theadd
method.- Similarly, the
willCallRealMethod().given(mathService).subtract(anyInt(), anyInt());
method configures the mockMathService
to call the realsubtract
method when it is called with any integer arguments. This allows thesubtractNumbers
method of theCalculatorService
class to be tested with the real behavior of thesubtract
method.
Verifying Interactions:
- The
then(mathService).should().add(5, 3);
andthen(mathService).should().subtract(10, 4);
methods verify that theadd
andsubtract
methods were called on theMathService
with the specified arguments. This ensures that theaddNumbers
andsubtractNumbers
methods of theCalculatorService
class interact with theMathService
correctly.
- The
Additional Scenarios
Scenario: Combining Real and Mocked Methods
In this scenario, we will demonstrate how to combine real and mocked methods using BDDMockito.willCallRealMethod()
.
@Test
public void testAddAndSubtractNumbers() {
// Given
willCallRealMethod().given(mathService).add(anyInt(), anyInt());
given(mathService.subtract(anyInt(), anyInt())).willReturn(3);
// When
int addResult = calculatorService.addNumbers(5, 3);
int subtractResult = calculatorService.subtractNumbers(10, 7);
// Then
assertEquals(8, addResult);
assertEquals(3, subtractResult);
then(mathService).should().add(5, 3);
then(mathService).should().subtract(10, 7);
}
Explanation
- Combining Real and Mocked Methods:
- The
willCallRealMethod().given(mathService).add(anyInt(), anyInt());
method configures the mockMathService
to call the realadd
method when it is called with any integer arguments. - The
given(mathService.subtract(anyInt(), anyInt())).willReturn(3);
method configures the mockMathService
to return3
when thesubtract
method is called with any integer arguments. This allows theaddNumbers
andsubtractNumbers
methods of theCalculatorService
class to be tested with both real and mocked behaviors.
- The
Conclusion
Using BDDMockito.willCallRealMethod()
in Mockito allows you to write more readable and expressive tests that follow the Behavior-Driven Development (BDD) style. By using willCallRealMethod()
for calling real methods, you can handle various scenarios and control the behavior of mock objects. This step-by-step guide demonstrated how to effectively use BDDMockito.willCallRealMethod()
in your unit tests, covering different scenarios to ensure comprehensive testing of the CalculatorService
class.
Related Mockito BDDMockito Class Methods (Behavior-Driven Development Style)
Mockito BDDMockito
Mockito BDDMockito given()
Mockito BDDMockito willThrow()
Mockito BDDMockito willAnswer()
Mockito BDDMockito willReturn()
Mockito BDDMockito willDoNothing()
Mockito BDDMockito willCallRealMethod()
Mockito BDDMockito then()
Mockito BDDMockito.any()
Mockito BDDMockito.times()
Comments
Post a Comment
Leave Comment