I use org.junit.jupiter.api.Assertions
object to assert an exception is thrown:
Assertions.assertThrows(
InvalidParameterException.class,
() -> new ThrowingExceptionClass().doSomethingDangerous());
Simplified, the exception thrown has a variable part dateTime
in its message:
final String message = String.format("Either request is too old [dateTime=%s]", date);
new InvalidParameterException(message);
As of version I use 5.4.0
the Assertions
provide three methods checking the exception is thrown:
assertThrows(Class<T> expectedType, Executable executable)
assertThrows(Class<T> expectedType, Executable executable, String message)
assertThrows(Class<T> expectedType, Executable executable, Supplier<String> messageSupplier)
Neither of them provides a mechanism checking whether a String starts with another String. The last 2 methods only check whether the String is equal. How do I check easily whether the exception message starts with "Either request is too old"
since more message variations might occur within the same InvalidParameterException
?
I'd appreciate a method assertThrows(Class<T> expectedType, Executable executable, Predicate<String> messagePredicate)
where the predicate would provide the thrown message
and the assertion passes when if predicate returns true
such as:
Assertions.assertThrows(
InvalidParameterException.class,
() -> new ThrowingExceptionClass().doSomethingDangerous()
message -> message.startsWith("Either request is too old"));
Sadly, it doesn't exist. Any workaround?
The assertThrows()
method returns an exception instance of the expected type (if any). You can then manually get a message from is and check if it starts with the string you desire.
Here is a sample from doc
@Test
void exceptionTesting() {
Exception exception = assertThrows(ArithmeticException.class, () ->
calculator.divide(1, 0));
assertEquals("/ by zero", exception.getMessage());
}
You should test the content of the message text of an exception only if that message is a specified part of the API of the unit you are testing. But it is questionable whether you should do that.
The message text of exceptions should not normally be presented to users, as part of the UI of your application.
Specifying the content of the message text encourages clients of the API to parse that message text to learn specific information about the exceptional condition. This is tricky, error prone and unnecessary. In your case, clients might be tempted to parse the message text to extract the date
value.
Instead, create a custom exception type that more specifically describes the exceptional condition. In your case, you would want your custom exception class to extend InvalidParameterException
. Your custom exception class could have a date field to make the additional data available. You unit test could check that the method under test throws an exception of the correct type, and that it has a date field with the correct value.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With