🎓 Top 15 Udemy Courses (80-90% Discount): My Udemy Courses - Ramesh Fadatare — All my Udemy courses are real-time and project oriented courses.
▶️ Subscribe to My YouTube Channel (178K+ subscribers): Java Guides on YouTube
▶️ For AI, ChatGPT, Web, Tech, and Generative AI, subscribe to another channel: Ramesh Fadatare on YouTube
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
@Mockannotation creates a mock instance of theMathServiceclass. This mock instance can be used to simulate the behavior of theMathServicein a controlled way.
- The
Injecting Mocks with
@InjectMocks:- The
@InjectMocksannotation injects the mockMathServiceinto theCalculatorServiceinstance to provide a controlled test environment. This allows theCalculatorServicemethods to be tested in isolation from the actualMathServiceimplementation.
- The
Using BDDMockito:
willCallRealMethod(): ThewillCallRealMethod().given(mathService).add(anyInt(), anyInt());method configures the mockMathServiceto call the realaddmethod when it is called with any integer arguments. This allows theaddNumbersmethod of theCalculatorServiceclass to be tested with the real behavior of theaddmethod.- Similarly, the
willCallRealMethod().given(mathService).subtract(anyInt(), anyInt());method configures the mockMathServiceto call the realsubtractmethod when it is called with any integer arguments. This allows thesubtractNumbersmethod of theCalculatorServiceclass to be tested with the real behavior of thesubtractmethod.
Verifying Interactions:
- The
then(mathService).should().add(5, 3);andthen(mathService).should().subtract(10, 4);methods verify that theaddandsubtractmethods were called on theMathServicewith the specified arguments. This ensures that theaddNumbersandsubtractNumbersmethods of theCalculatorServiceclass interact with theMathServicecorrectly.
- 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 mockMathServiceto call the realaddmethod when it is called with any integer arguments. - The
given(mathService.subtract(anyInt(), anyInt())).willReturn(3);method configures the mockMathServiceto return3when thesubtractmethod is called with any integer arguments. This allows theaddNumbersandsubtractNumbersmethods of theCalculatorServiceclass 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