Introduction
BDDMockito.willDoNothing()
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 do nothing. This is particularly useful when you need to test void methods without any side effects or when you want to ignore certain method calls in your tests. This tutorial will demonstrate how to use BDDMockito.willDoNothing()
to mock void 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 NotificationService
class that has a dependency on an EmailService
. Our goal is to test the NotificationService
methods using BDDMockito.willDoNothing()
to mock void methods.
NotificationService and EmailService Classes
First, create the Email
class, the EmailService
interface, and the NotificationService
class.
public class Email {
private String recipient;
private String message;
// Constructor, getters, and setters
public Email(String recipient, String message) {
this.recipient = recipient;
this.message = message;
}
public String getRecipient() {
return recipient;
}
public void setRecipient(String recipient) {
this.recipient = recipient;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}
public interface EmailService {
void sendEmail(Email email);
}
public class NotificationService {
private final EmailService emailService;
public NotificationService(EmailService emailService) {
this.emailService = emailService;
}
public void sendNotification(String recipient, String message) {
Email email = new Email(recipient, message);
emailService.sendEmail(email);
}
}
JUnit 5 Test Class with BDDMockito
Create a test class for NotificationService
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 NotificationServiceTest {
@Mock
private EmailService emailService;
@InjectMocks
private NotificationService notificationService;
@Test
public void testSendNotification() {
// Given
String recipient = "test@example.com";
String message = "Hello, World!";
willDoNothing().given(emailService).sendEmail(any(Email.class));
// When
notificationService.sendNotification(recipient, message);
// Then
then(emailService).should().sendEmail(any(Email.class));
}
}
Explanation
Creating Mocks with
@Mock
:- The
@Mock
annotation creates a mock instance of theEmailService
interface. This mock instance can be used to simulate the behavior of theEmailService
in a controlled way.
- The
Injecting Mocks with
@InjectMocks
:- The
@InjectMocks
annotation injects the mockEmailService
into theNotificationService
instance to provide a controlled test environment. This allows theNotificationService
methods to be tested in isolation from the actualEmailService
implementation.
- The
Using BDDMockito:
willDoNothing()
: ThewillDoNothing().given(emailService).sendEmail(any(Email.class));
method configures the mockEmailService
to do nothing when thesendEmail
method is called with anyEmail
object. This allows thesendNotification
method of theNotificationService
class to be tested without side effects.
Verifying Interactions:
- The
then(emailService).should().sendEmail(any(Email.class));
method verifies that thesendEmail
method was called on theEmailService
with anyEmail
object. This ensures that thesendNotification
method of theNotificationService
class interacts with theEmailService
correctly.
- The
Additional Scenarios
Scenario: Verifying No More Interactions
In this scenario, we will demonstrate how to verify that no more interactions occurred with the mock object using BDDMockito
.
@Test
public void testNoMoreInteractionsWithEmailService() {
// Given
String recipient = "test@example.com";
String message = "Hello, World!";
willDoNothing().given(emailService).sendEmail(any(Email.class));
// When
notificationService.sendNotification(recipient, message);
// Then
then(emailService).should().sendEmail(any(Email.class));
then(emailService).shouldHaveNoMoreInteractions();
}
Explanation
- Verifying No More Interactions:
- The
then(emailService).shouldHaveNoMoreInteractions();
method verifies that no more interactions occurred with theEmailService
mock object after thesendEmail
method was called. This ensures that no unintended interactions happened with theEmailService
.
- The
Scenario: Handling Multiple Calls with BDDMockito
In this scenario, we will demonstrate how to handle multiple method calls using BDDMockito.willDoNothing()
.
@Test
public void testSendMultipleNotifications() {
// Given
String recipient1 = "test1@example.com";
String message1 = "Hello, World!";
String recipient2 = "test2@example.com";
String message2 = "Goodbye, World!";
willDoNothing().given(emailService).sendEmail(any(Email.class));
// When
notificationService.sendNotification(recipient1, message1);
notificationService.sendNotification(recipient2, message2);
// Then
then(emailService).should(times(2)).sendEmail(any(Email.class));
}
Explanation
- Handling Multiple Calls with BDDMockito:
- The
then(emailService).should(times(2)).sendEmail(any(Email.class));
method verifies that thesendEmail
method was called on theEmailService
exactly twice with anyEmail
object. This ensures that thesendNotification
method of theNotificationService
class interacts with theEmailService
the expected number of times.
- The
Conclusion
Using BDDMockito.willDoNothing()
in Mockito allows you to write more readable and expressive tests that follow the Behavior-Driven Development (BDD) style. By using willDoNothing()
for stubbing void methods, you can handle various scenarios and control the behavior of mock objects. This step-by-step guide demonstrated how to effectively use BDDMockito.willDoNothing()
in your unit tests, covering different scenarios to ensure comprehensive testing of the NotificationService
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