Mockito's `thenReturn()` and `thenThrow()` methods are used to define the behavior of mock objects in unit tests. Here's how they interact with other Mockito methods:
`thenReturn()`
- Purpose: This method is used to specify a return value for a method call on a mock object. It allows you to define what value should be returned when a specific method is invoked.
- Usage: It is typically used in a method chain starting with `when()`, as in `when(mockObject.method()).thenReturn(returnValue)`.
- Multiple Values: You can specify multiple return values for consecutive calls by chaining `thenReturn()` multiple times or by passing multiple values to a single `thenReturn()` call. The last value specified will be returned for all subsequent calls.
java
when(passwordEncoder.encode("1")).thenReturn("a", "b");
// or
when(passwordEncoder.encode("1"))
.thenReturn("a")
.thenReturn("b");
`thenThrow()`
- Purpose: This method is used to specify that a method call on a mock object should throw an exception. It is particularly useful for testing how your code handles exceptions from dependencies.
- Usage: Similar to `thenReturn()`, it is used in a method chain starting with `when()`, as in `when(mockObject.method()).thenThrow(exception)`.
- Interaction with `thenReturn()`: You can use both methods to define different behaviors for the same mock method, depending on the context of your test. For example, you might want to test both successful and exception scenarios.
java
// Successful scenario
when(mockObject.method()).thenReturn(successValue);
// Exception scenario
when(mockObject.method()).thenThrow(new ExceptionType());
Interaction with Other Mockito Methods
- `doReturn()` and `doThrow()`: These methods serve similar purposes to `thenReturn()` and `thenThrow()`, respectively, but are used differently. They are typically used with spies (`@Spy`) to avoid calling the real method, which might have side effects. `doReturn()` and `doThrow()` are less readable and should be used when necessary, such as when working with spies.
java
// Using doReturn() with a spy
doReturn(returnValue).when(spyObject).method();
// Using doThrow() with a spy
doThrow(exception).when(spyObject).method();
- `thenAnswer()` and `doAnswer()`: These methods allow for more complex logic by providing a custom implementation of the `Answer` interface. They can be used to perform actions based on the arguments passed to the method or to return dynamic values.
java
when(mockObject.method()).thenAnswer(invocation -> {
// Custom logic here
return dynamicValue;
});
Consecutive Calls
Mockito allows you to define different behaviors for consecutive calls to the same method. This can be useful for testing scenarios where the behavior changes based on previous interactions.
java
when(mockObject.method())
.thenReturn(firstValue)
.thenThrow(exception)
.thenReturn(secondValue);
In this example, the first call returns `firstValue`, the second call throws an exception, and any subsequent calls return `secondValue`.
Summary
`thenReturn()` and `thenThrow()` are fundamental methods in Mockito for defining the behavior of mock objects. They can be used together with other Mockito methods like `doReturn()`, `doThrow()`, `thenAnswer()`, and `doAnswer()` to create complex test scenarios. Understanding how these methods interact allows you to write comprehensive unit tests that cover a wide range of application behaviors.
Citations:[1] https://www.vogella.com/tutorials/Mockito/article.html
[2] https://www.javaguides.net/2023/10/mockito-thenthrow.html
[3] https://decode.agency/article/using-mockito-in-kotlin/
[4] https://www.toptal.com/java/a-guide-to-everyday-mockito
[5] https://dev.to/realnamehidden1_61/thenthrow-method-in-mockito-example-460l
[6] https://stackoverflow.com/questions/4180209/mockito-re-stub-method-already-stubbed-with-thenthrow
[7] https://site.mockito.org/javadoc/current/org/mockito/Mockito.html
[8] https://stackoverflow.com/questions/47128320/mockito-understanding-how-when-thenthrow-function-works