In Mockito, handling exceptions with `thenThrow()` differs significantly between void and non-void methods due to their inherent nature and how Mockito is designed to handle them.
Non-Void Methods
For non-void methods, `when().thenThrow()` is the standard approach to mock exceptions. This method is used when you want a specific method to throw an exception when it is called. The syntax involves setting up a mock object, specifying the method call with `when()`, and then defining the exception to be thrown using `thenThrow()`.
Here's an example:
java
import static org.mockito.Mockito.*;
import org.junit.jupiter.api.Test;
class MyServiceTest {
@Test
void testThrowException() {
MyClass mockClass = mock(MyClass.class);
when(mockClass.someMethod()).thenThrow(new RuntimeException("An error occurred"));
assertThrows(RuntimeException.class, () -> {
mockClass.someMethod();
});
}
}
In this case, `someMethod()` is a non-void method, and `when().thenThrow()` is used to simulate an exception.
Void Methods
For void methods, you cannot use `when().thenThrow()` because void methods do not return a value, which is necessary for the `when()` method to work. Instead, Mockito provides the `doThrow()` method to handle exceptions in void methods.
Here's how you can use `doThrow()`:
java
import static org.mockito.Mockito.*;
import org.junit.jupiter.api.Test;
class MyServiceTest {
@Test
void testThrowExceptionInVoidMethod() {
MyClass mockClass = mock(MyClass.class);
doThrow(new IllegalArgumentException("Invalid argument")).when(mockClass).voidMethod();
assertThrows(IllegalArgumentException.class, () -> {
mockClass.voidMethod();
});
}
}
In this example, `voidMethod()` is a void method, and `doThrow()` is used to simulate an exception when it is called.
Key Differences
- Return Type: Non-void methods return a value, allowing `when().thenThrow()` to be used. Void methods do not return a value, requiring `doThrow()` instead.
- Syntax: The syntax for setting up the mock differs slightly between `when().thenThrow()` and `doThrow().when()`.
- Use Cases: `when().thenThrow()` is suitable for methods that return values, while `doThrow()` is necessary for methods without return values.
In summary, `thenThrow()` is not directly applicable to void methods due to their lack of return type, necessitating the use of `doThrow()` for mocking exceptions in such methods.
Citations:[1] https://www.browserstack.com/guide/mockito-throw-exception
[2] http://bwagner.org/ibhl1/csregular/unit13_javaMethods2/notes/01_nonVoid.html
[3] https://stackoverflow.com/questions/54020425/how-to-dothrow-or-thenthrow-on-method-that-returns-void-and-throws-an-exception
[4] https://stackoverflow.com/questions/15156857/mockito-test-a-void-method-throws-an-exception
[5] https://www.cs.utexas.edu/~mitra/csSpring2006/cs313/lectures/excep.html
[6] https://learn.microsoft.com/en-us/dotnet/standard/exceptions/best-practices-for-exceptions
[7] https://www.javacodegeeks.com/2020/06/mock-void-method-with-mockito.html
[8] https://www.reddit.com/r/learnprogramming/comments/aty35g/eli5_java_void_vs_nonvoid_method_help/
[9] https://rollbar.com/blog/how-to-use-the-throws-keyword-in-java-and-when-to-use-throw/