Introduction
BDDMockito.then()
is a method provided by Mockito to support the Behavior-Driven Development (BDD) style of writing tests. It is used to verify interactions with mock objects in a more readable and expressive way. This tutorial will demonstrate how to use BDDMockito.then()
to verify method calls on mock objects.
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 UserService
class that has a dependency on a UserRepository
. Our goal is to test the UserService
methods using BDDMockito.then()
to verify method calls.
UserService and UserRepository Classes
First, create the User
class, the UserRepository
interface, and the UserService
class.
public class User {
private String name;
private String email;
// Constructor, getters, and setters
public User(String name, String email) {
this.name = name;
this.email = email;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
}
public interface UserRepository {
void saveUser(User user);
User findUserByEmail(String email);
List<User> findAllUsers();
}
public class UserService {
private final UserRepository userRepository;
public UserService(UserRepository userRepository) {
this.userRepository = userRepository;
}
public void registerUser(String name, String email) {
User user = new User(name, email);
userRepository.saveUser(user);
}
public User getUserByEmail(String email) {
return userRepository.findUserByEmail(email);
}
public List<User> getAllUsers() {
return userRepository.findAllUsers();
}
}
JUnit 5 Test Class with BDDMockito
Create a test class for UserService
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;
import java.util.Arrays;
import java.util.List;
@ExtendWith(MockitoExtension.class)
public class UserServiceTest {
@Mock
private UserRepository userRepository;
@InjectMocks
private UserService userService;
@Test
public void testRegisterUser() {
// Given
String name = "Ramesh Fadatare";
String email = "ramesh.fadatare@example.com";
// When
userService.registerUser(name, email);
// Then
then(userRepository).should().saveUser(any(User.class));
}
@Test
public void testGetUserByEmail() {
// Given
String email = "anita.patil@example.com";
User user = new User("Anita Patil", email);
given(userRepository.findUserByEmail(email)).willReturn(user);
// When
User result = userService.getUserByEmail(email);
// Then
assertNotNull(result);
assertEquals("Anita Patil", result.getName());
assertEquals(email, result.getEmail());
then(userRepository).should().findUserByEmail(email);
}
@Test
public void testGetAllUsers() {
// Given
User user1 = new User("Ravi Kumar", "ravi.kumar@example.com");
User user2 = new User("Rajesh Verma", "rajesh.verma@example.com");
List<User> users = Arrays.asList(user1, user2);
given(userRepository.findAllUsers()).willReturn(users);
// When
List<User> result = userService.getAllUsers();
// Then
assertNotNull(result);
assertEquals(2, result.size());
assertEquals("Ravi Kumar", result.get(0).getName());
assertEquals("Rajesh Verma", result.get(1).getName());
then(userRepository).should().findAllUsers();
}
@Test
public void testRegisterUserWithCustomMatcher() {
// Given
String name = "Anjali Sharma";
String email = "anjali.sharma@example.com";
// When
userService.registerUser(name, email);
// Then
then(userRepository).should().saveUser(argThat(user -> user.getName().equals("Anjali Sharma") && user.getEmail().equals("anjali.sharma@example.com")));
}
}
Explanation
Creating Mocks with
@Mock
:- The
@Mock
annotation creates a mock instance of theUserRepository
interface. This mock instance can be used to simulate the behavior of theUserRepository
in a controlled way.
- The
Injecting Mocks with
@InjectMocks
:- The
@InjectMocks
annotation injects the mockUserRepository
into theUserService
instance to provide a controlled test environment. This allows theUserService
methods to be tested in isolation from the actualUserRepository
implementation.
- The
Using BDDMockito:
then()
: Thethen(userRepository).should().saveUser(any(User.class));
method verifies that thesaveUser
method was called on theUserRepository
with anyUser
object. This allows theregisterUser
method of theUserService
class to be tested with controlled interactions.- Similarly, the
then(userRepository).should().findUserByEmail(email);
andthen(userRepository).should().findAllUsers();
methods verify that the respective methods were called on theUserRepository
.
Using Custom Matchers:
- The
then(userRepository).should().saveUser(argThat(user -> user.getName().equals("Anjali Sharma") && user.getEmail().equals("anjali.sharma@example.com")));
method verifies that thesaveUser
method was called on theUserRepository
with aUser
object that matches the specified name and email.
- The
Additional Scenarios
Scenario: Verifying No Interactions
In this scenario, we will demonstrate how to verify that no interactions occurred with the mock object using BDDMockito
.
@Test
public void testNoInteractionsWithUserRepository() {
// Given
// No interactions expected
// When
// No method calls
// Then
then(userRepository).shouldHaveNoInteractions();
}
Explanation
- Verifying No Interactions:
- The
then(userRepository).shouldHaveNoInteractions();
method verifies that no interactions occurred with theUserRepository
mock object. This ensures that theUserRepository
was not used during the test.
- The
Scenario: Verifying Method Call Order
In this scenario, we will demonstrate how to verify the order of method calls using BDDMockito
.
@Test
public void testMethodCallOrder() {
// Given
String name = "Ramesh Fadatare";
String email = "ramesh.fadatare@example.com";
User user = new User(name, email);
given(userRepository.findUserByEmail(email)).willReturn(user);
// When
userService.registerUser(name, email);
userService.getUserByEmail(email);
// Then
InOrder inOrder = inOrder(userRepository);
then(userRepository).should(inOrder).saveUser(any(User.class));
then(userRepository).should(inOrder).findUserByEmail(email);
}
Explanation
- Verifying Method Call Order:
- The
InOrder inOrder = inOrder(userRepository);
statement creates anInOrder
object to verify the order of interactions with theUserRepository
mock object. - The
then(userRepository).should(inOrder).saveUser(any(User.class));
andthen(userRepository).should(inOrder).findUserByEmail(email);
methods verify that thesaveUser
method was called before thefindUserByEmail
method on theUserRepository
.
- The
Conclusion
Using BDDMockito.then()
in Mockito allows you to write more readable and expressive tests that follow the Behavior-Driven Development (BDD) style. By using then()
for verifying method calls, you can handle various scenarios and control the interactions with mock objects. This step-by-step guide demonstrated how to effectively use BDDMockito.then()
in your unit tests, covering different scenarios to ensure comprehensive testing of the UserService
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