The doAnswer method in Mockito is used to stub a void method with a generic answer. This allows you to specify custom behavior when the void method is called. The Answer interface provides a way to define this behavior by implementing the answer method, which gets invoked when the stubbed method is called.
Table of Contents
- Introduction
doAnswerMethod Syntax- Examples
- Basic Usage
- Custom Answer Logic
- Real-World Use Case
- Conclusion
Introduction
Mockito is a popular library in Java for creating and managing mock objects. The doAnswer method allows you to stub void methods with custom behavior, which can be useful for more complex testing scenarios where simple stubbing with doNothing, doThrow, or doReturn is not sufficient.
doAnswer Method Syntax
Stubbing a Void Method with a Generic Answer
static Stubber doAnswer(Answer answer)
Sets custom behavior for a void method when it is called.
Parameters:
answer: An implementation of theAnswerinterface, defining the custom behavior to execute when the method is called.
Returns:
- A
Stubberobject that allows further stubbing configurations.
Examples
Basic Usage
Stub a void method with a simple custom answer.
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.verify;
import org.mockito.stubbing.Answer;
import org.junit.jupiter.api.Test;
public class BasicDoAnswerTest {
@Test
void testDoAnswer() {
UserService mockUserService = mock(UserService.class);
// Stub the deleteUser method with a custom answer
doAnswer((Answer<Void>) invocation -> {
String userId = invocation.getArgument(0);
System.out.println("User " + userId + " deleted");
return null;
}).when(mockUserService).deleteUser("123");
// Call the method
mockUserService.deleteUser("123");
// Verify that the method was called
verify(mockUserService).deleteUser("123");
}
}
class UserService {
public void deleteUser(String userId) {
// Method implementation
}
}
Custom Answer Logic
Stub a void method with more complex custom logic using the Answer interface.
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.verify;
import org.mockito.stubbing.Answer;
import org.junit.jupiter.api.Test;
public class CustomDoAnswerTest {
@Test
void testDoAnswerWithCustomLogic() {
UserService mockUserService = mock(UserService.class);
// Stub the deleteUser method with custom logic
doAnswer((Answer<Void>) invocation -> {
String userId = invocation.getArgument(0);
if ("admin".equals(userId)) {
throw new IllegalArgumentException("Cannot delete admin user");
}
System.out.println("User " + userId + " deleted");
return null;
}).when(mockUserService).deleteUser("admin");
// Call the method and expect an exception
assertThrows(IllegalArgumentException.class, () -> mockUserService.deleteUser("admin"));
// Verify that the method was called
verify(mockUserService).deleteUser("admin");
}
}
class UserService {
public void deleteUser(String userId) {
// Method implementation
}
}
Real-World Use Case
Testing a Service Method with Complex Dependencies
In a real-world scenario, you might have a service class that calls a void method on a dependency. Using doAnswer, you can configure the void method to execute custom logic during your test.
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.verify;
import org.mockito.stubbing.Answer;
import org.junit.jupiter.api.Test;
interface NotificationService {
void sendNotification(String message);
}
class UserService {
private final NotificationService notificationService;
public UserService(NotificationService notificationService) {
this.notificationService = notificationService;
}
public void deleteUser(String userId) {
// Perform user deletion logic
notificationService.sendNotification("User " + userId + " deleted");
}
}
public class UserServiceTest {
@Test
void testDeleteUserWithCustomNotification() {
NotificationService mockNotificationService = mock(NotificationService.class);
UserService userService = new UserService(mockNotificationService);
// Stub the sendNotification method with custom logic
doAnswer((Answer<Void>) invocation -> {
String message = invocation.getArgument(0);
System.out.println("Sending notification: " + message);
return null;
}).when(mockNotificationService).sendNotification("User 123 deleted");
// Call the deleteUser method
userService.deleteUser("123");
// Verify that the sendNotification method was called
verify(mockNotificationService).sendNotification("User 123 deleted");
}
}
In this example, the UserServiceTest class uses Mockito’s doAnswer method to configure the sendNotification method of the NotificationService interface to execute custom logic when called. The test verifies that the sendNotification method is called with the expected message during the execution of the deleteUser method in the UserService class.
Conclusion
The doAnswer method in Mockito is used for stubbing void methods with custom behavior. By using doAnswer and implementing the Answer interface, you can define complex logic to be executed when void methods are called. This allows you to create flexible and comprehensive tests for your Java applications.