简体   繁体   English

如何使用 jUnit 5 断言检查异常消息是否以字符串开头?

[英]How to use jUnit 5 Assertions to check, whether exception message starts with a String?

I use org.junit.jupiter.api.Assertions object to assert an exception is thrown:我使用org.junit.jupiter.api.Assertions object 断言抛出异常:

Assertions.assertThrows(
        InvalidParameterException.class,
        () -> new ThrowingExceptionClass().doSomethingDangerous());

Simplified, the exception thrown has a variable part dateTime in its message:简化后,抛出的异常在其消息中具有可变部分dateTime

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:从我使用5.4.0的版本开始, Assertions提供了三种检查异常是否抛出的方法:

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 ?我如何轻松检查异常消息是否以"Either request is too old"开头,因为在同一个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:我很欣赏assertThrows(Class<T> expectedType, Executable executable, Predicate<String> messagePredicate) ,其中谓词将提供抛出的message ,并且当谓词返回true时断言通过,例如:

Assertions.assertThrows(
    InvalidParameterException.class,
    () -> new ThrowingExceptionClass().doSomethingDangerous()
    message -> message.startsWith("Either request is too old"));

Sadly, it doesn't exist.可悲的是,它不存在。 Any workaround?任何解决方法?

assertThrows returns you an exception instance of the expected type (if any). assertThrows 为您返回预期类型的异常实例(如果有)。 You can then manually get a message from is and check if it starts with the string you desire.然后,您可以手动从 is 获取消息并检查它是否以您想要的字符串开头。

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.只有当消息是您正在测试的单元的 API 的指定部分时,您才应该测试异常消息文本的内容。 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.异常的消息文本通常不应作为应用程序 UI 的一部分呈现给用户

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.指定消息文本的内容会鼓励 API 的客户端解析该消息文本以了解有关异常情况的特定信息。 This is tricky, error prone and unnecessary.这很棘手,容易出错且不必要。 In your case, clients might be tempted to parse the message text to extract the date value.在您的情况下,客户端可能会试图解析消息文本以提取date值。

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 .在您的情况下,您希望自定义异常 class 扩展InvalidParameterException Your custom exception class could have a date field to make the additional data available.您的自定义异常 class 可能有一个日期字段以提供其他数据。 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.您的单元测试可以检查被测方法是否引发了正确类型的异常,以及它是否具有具有正确值的日期字段。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM