Introduction
In this chapter, we will learn about BDD (Behavior Driven Development) style mocking using Mockito. BDD encourages collaboration between developers, QA, and non-technical or business participants in a software project. Mockito supports BDD-style mocking, which can make tests more readable and align them with the BDD principles.
What is BDD?
Behavior Driven Development (BDD) is an extension of Test Driven Development (TDD) that focuses on the behavioral aspects of an application. BDD promotes collaboration between all stakeholders in a project (developers, testers, and business analysts) to ensure the software meets business requirements. BDD uses natural language constructs (like Given, When, Then) to describe the behavior of a system.
Key Concepts of BDD
- Given: The initial context or state before an action is performed.
- When: The action or event that triggers the behavior.
- Then: The expected outcome or result after the action is performed.
BDDMockito Overview
Mockito provides a BDD style API through the BDDMockito
class. This API uses methods like given
, willReturn
, willThrow
, then
, and should
to define mock behavior and verify interactions.
Syntax of BDDMockito
- Given: Use
given
to set up the precondition.given(mock.method()).willReturn(value);
- When: The action is implied when the method under test is called.
// method under test result = mock.method();
- Then: Use
then
andshould
to verify interactions.then(mock).should().method();
Example: CalculatorService Class and CalculatorTest Class
Class Under Test: CalculatorService
public class CalculatorService {
private final MathService mathService;
public CalculatorService(MathService mathService) {
this.mathService = mathService;
}
public int add(int a, int b) {
return mathService.add(a, b);
}
public int subtract(int a, int b) {
return mathService.subtract(a, b);
}
}
Supporting Class: MathService
public class MathService {
public int add(int a, int b) {
return a + b;
}
public int subtract(int a, int b) {
return a - b;
}
}
Test Class: CalculatorTest
import static org.mockito.BDDMockito.*;
import org.junit.jupiter.api.Test;
import org.mockito.Mockito;
import static org.junit.jupiter.api.Assertions.*;
public class CalculatorTest {
@Test
void testAdd_BDDStyle() {
// Given
MathService mathService = Mockito.mock(MathService.class);
CalculatorService calculatorService = new CalculatorService(mathService);
given(mathService.add(10, 20)).willReturn(30);
// When
int result = calculatorService.add(10, 20);
// Then
assertEquals(30, result);
then(mathService).should().add(10, 20);
}
@Test
void testSubtract_BDDStyle() {
// Given
MathService mathService = Mockito.mock(MathService.class);
CalculatorService calculatorService = new CalculatorService(mathService);
given(mathService.subtract(20, 10)).willReturn(10);
// When
int result = calculatorService.subtract(20, 10);
// Then
assertEquals(10, result);
then(mathService).should().subtract(20, 10);
}
}
Explanation
-
Given:
MathService mathService = Mockito.mock(MathService.class); CalculatorService calculatorService = new CalculatorService(mathService); given(mathService.add(10, 20)).willReturn(30);
These lines set up the mock and the class under test. The
given
method defines the expected behavior of the mock. -
When:
int result = calculatorService.add(10, 20);
This line calls the method under test.
-
Then:
assertEquals(30, result); then(mathService).should().add(10, 20);
These lines verify the result and check that the mock method was called as expected.
Conclusion
BDD style mocking in Mockito makes tests more readable and aligns them with BDD principles. By using given-willReturn
and then-should
syntax, you can create more expressive tests that are easier to understand and maintain. In this chapter, we demonstrated how to use BDD style mocking with a simple CalculatorService
example. This approach helps improve collaboration and communication between team members, making your tests more effective and aligned with business requirements. Understanding and utilizing BDDMockito will help you write more readable and maintainable tests.