Mockito doAnswer()

1. Overview

The Mockito.doAnswer() method is an invaluable tool when you wish to simulate complex behaviors in your mock objects during testing. This method allows you to implement custom logic in response to method invocations on your mock. The utility shines particularly when you need to examine arguments, adjust multiple fields, or test callback mechanisms. In this tutorial, we will dive deep into the doAnswer() method and grasp its practical uses.

2. Development Steps

1. Set up a new Maven project.

2. Incorporate the required Mockito and JUnit 5 dependencies.

3. Create a simple class named 'Database' to demonstrate the usage of doAnswer().

4. Design a test class to showcase the Mockito.doAnswer() application.

5. Execute the test cases and review the results.

6. Understand the outcomes.

3. Dependencies (Mockito and JUnit 5)

<!-- JUnit 5 -->
<dependency>
    <groupId>org.junit.jupiter</groupId>
    <artifactId>junit-jupiter-engine</artifactId>
    <version>5.10.0</version>
    <scope>test</scope>
</dependency>
<!-- Mockito -->
<dependency>
    <groupId>org.mockito</groupId>
    <artifactId>mockito-core</artifactId>
    <version>5.6.0</version>
    <scope>test</scope>
</dependency>

4. Code Program

// Step 3: Define the Database class
class Database {
    void save(String data, Callback callback) {
        // Simulating a database save operation
        callback.onSuccess();
    }
}
interface Callback {
    void onSuccess();
    void onFailure(String reason);
}
// Step 4: Develop the test class for Database
import org.junit.jupiter.api.Test;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.doAnswer;
public class DatabaseTest {
    @Test
    public void testDoAnswer() {
        // Create a mock of Database
        Database mockDatabase = mock(Database.class);
        // Implement the doAnswer logic
        doAnswer(invocation -> {
            String data = invocation.getArgument(0);
            Callback callback = invocation.getArgument(1);
            if ("validData".equals(data)) {
                callback.onSuccess();
            } else {
                callback.onFailure("Invalid Data");
            }
            return null; // Since our save method has a void return type
        }).when(mockDatabase).save("validData", new Callback() {
            @Override
            public void onSuccess() {
                System.out.println("Data Saved Successfully!");
            }
            @Override
            public void onFailure(String reason) {
                System.out.println("Data Saving Failed: " + reason);
            }
        });
        // Invoke the method
        mockDatabase.save("validData", new Callback() {
            @Override
            public void onSuccess() {
                System.out.println("Data Saved Successfully!");
            }
            @Override
            public void onFailure(String reason) {
                System.out.println("Data Saving Failed: " + reason);
            }
        });
    }
}

Output:

The console will display:
Data Saved Successfully!

Code Explanation:

1. We began with a basic Database class and a corresponding Callback interface. The save method in the Database class simulates a database save operation.

2. In our test, we created a mock of the Database class.

3. Using doAnswer(), we defined custom logic to simulate the behavior of our save method, deciding whether the onSuccess() or onFailure() method of our callback gets executed based on the data provided.

4. The logic checks if the data is "validData", indicating success; otherwise, it calls the failure callback.

5. Conclusion

The Mockito.doAnswer() method provides a dynamic way to define custom behavior for mock object methods. This facility allows testers and developers to implement complex scenarios, validate callbacks, and ensure comprehensive testing. By mastering this method, you can make your testing scenarios more robust and adaptive.

Related Mockito Methods

Mockito mock()
Mockito spy()
Mockito when()
Mockito thenThrow()
Mockito verify()
Mockito times()
Mockito never()
Mockito any()
Mockito eq()
Mockito inOrder()
Mockito doReturn()
Mockito doThrow()
Mockito doAnswer()
Mockito timeout()
Mockito ArgumentMatchers

Comments