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
doAnswer
Method 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 theAnswer
interface, defining the custom behavior to execute when the method is called.
Returns:
- A
Stubber
object 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.