Understanding Mockito's When-Then vs Do-When: Key Differences
- Published on
Understanding Mockito's When-Then vs Do-When: Key Differences
Mockito is a popular mocking framework for Java that allows developers to create mock objects and define their behavior in unit tests. Properly utilizing Mockito not only makes your tests more straightforward but also significantly enhances the maintainability and reliability of your code. In this blog post, we will dive into two commonly used Mockito constructs: when-then and do-when. We will explore their differences, scenarios for use, and how to choose between them, providing code snippets as illustrative examples.
What is Mockito?
Mockito is an open-source Java library specifically designed for unit testing. It enables developers to create mock objects, allowing for the testing of code in isolation. This is crucial to ensure that your unit tests only cover specific parts of your application without relying on external dependencies such as databases, APIs, or other classes.
When-Then Structure
The when-then construct can be used to define what should happen when a specific method is invoked on a mock object. It is the most commonly used way to stub out responses from mock objects.
Syntax of When-Then
when(mock.method()).thenReturn(value);
Code Example
Let’s say you have a simple Calculator
interface. Below is how you would mock its behavior using the when-then structure.
import static org.mockito.Mockito.*;
public class CalculatorTest {
@Test
public void testAddition() {
// Create a mock object of Calculator
Calculator calculator = mock(Calculator.class);
// Define behavior with ‘when-then’
when(calculator.add(2, 3)).thenReturn(5);
// Test the method
assertEquals(5, calculator.add(2, 3));
}
}
Explanation
In this example:
- We create a mock instance of the
Calculator
interface. - We use the
when(...).thenReturn(...)
pattern to specify that when theadd
method is called with parameters (2, 3), it should return 5. - The test verifies that the mocked
add
method behaves as defined.
The when-then structure is intuitive and works perfectly for simple stubbing scenarios. However, there are cases when using do-when is more suitable.
Do-When Structure
The do-when construct differs in that it allows you to handle void methods and respond to method calls in a slightly different manner. It is ideal for cases where the method being mocked is void and does not return a value.
Syntax of Do-When
doNothing().when(mock).method();
Code Example
Consider a scenario where we have a Database
interface with a save
method that doesn't return a value.
import static org.mockito.Mockito.*;
public class DatabaseTest {
@Test
public void testSave() {
// Create mock of Database
Database database = mock(Database.class);
// Define behavior with ‘do-when’
doNothing().when(database).save(any(Data.class));
// Call the method to be tested
database.save(new Data("Example"));
// Verify the interaction
verify(database).save(any(Data.class));
}
}
Explanation
In this example:
- A mock instance of the
Database
interface is created. - The
doNothing().when(...).save(...)
pattern is used becausesave
is a void method (it does not return a value). - We then call the
save
method and verify that it has been called with any instance ofData
.
Key Differences Between When-Then and Do-When
-
Return Type:
- when-then: Primarily used for methods that return a value.
- do-when: Used for void methods where you cannot directly return a value.
-
Verbosity:
- when-then: More straightforward and easier to read, especially for returning values.
- do-when: Slightly more verbose but provides flexibility in certain scenarios.
-
Use Cases:
- when-then: Ideal for stubbing methods like
add
,subtract
, etc., that provide direct output. - do-when: Better suited for scenarios like logging, updating a database, or any other situation where the focus is on the method execution rather than its return value.
- when-then: Ideal for stubbing methods like
-
Flexibility:
- The do-when mechanism provides more flexibility when you need to simulate exceptions or manage state changes.
When to Use What?
Best Use Cases for When-Then
Use when-then when:
- Stubbing methods are returning an object.
- Your testing scenario focuses primarily on the output of method calls.
Best Use Cases for Do-When
Use do-when when:
- You are working with void methods.
- You need to simulate side effects like throwing exceptions, which can only be done using the do-when syntax.
Key Takeaways
Understanding the difference between when-then and do-when is crucial for effective and efficient mocking in unit tests. Choosing the right approach depends on the method you are trying to mock and its return type.
By using these two different styles appropriately, you can create cleaner, more manageable tests that seriously enhance the maintainability of your codebase. It's all about picking the right tool for the job!
To dive deeper into Mockito and its features, check out the official Mockito documentation here for the latest updates and best practices.
By leveraging the power of Mockito, your unit tests can become not only more efficient but also more reliable — allowing for smoother development cycles and greater confidence in your code. Happy testing!
Checkout our other articles