java - AssertJ:使用 String.format 生成的消息测试异常

标签 java junit assertj

我想知道当使用 String.format() 生成该消息时,是否有一种干净且完整的方法可以对附加到引发的异常的消息进行断言。例如,像这样的类:

public class Car {

  public static final String DRIVE_ERROR = "Can't drive while car %s is parked!";

  private String name;
  private boolean parked;

  public Car(String name) {
    this.name = name;
    this.parked = true;
  }

  public void drive() {
    if (parked) {
      throw new IllegalStateException(String.format(DRIVE_ERROR, name));
    }
  }
}

(抱歉这个奇怪的例子,只是想让它尽可能简单) 现在,如果我要测试汽车,我会有这样的类(class):

public class CarTest {

  @Test
  public void drive_test() {
    Car car = new Car("Greased Lightning");
    assertThatThrownBy(() -> car.drive())
        .isInstanceOf(IllegalStateException.class)
        .hasMessageContaining("???");
  }
}

问题是,对消息进行断言的最佳方式是什么?在这个例子中,我可以分离出汽车名称的声明,然后自己使用 String 格式从 Car 中获取静态字符串并格式化名称,但这似乎有很多额外的代码,并且不能是在很多情况下都很容易使用(例如,当格式化字符串中的项目在运行时确定时)。我真正希望能够做的是将错误消息字符串传递给 hasMessageContaining 并让它忽略“%s”占位符并接受该位置的任何内容。有没有办法用assertJ 进行字符串的正则表达式匹配?或者其他一些干净利落的方法?

编辑:我也愿意接受抛出具有更容易测试消息的异常的替代方案。一种解决方案是仅使用字符串连接,例如抛出新的异常(STATIC_ERROR_MESSAGE + name),然后测试消息是否包含第一部分,但这确实限制了您的消息格式化能力,并且看起来不太干净.

最佳答案

与常规字符串断言相比,异常消息断言受到限制。 你可以做的是使用 matchescontainsPattern断言,例如:

@Test
public void test() {
  // GIVEN some preconditions

  // WHEN
  Throwable thrown = catchThrowableOfType(() -> { throw new IllegalStateException("boom!"); }, 
                                         IllegalStateException.class);
  // THEN
  assertThat(thrown.getMessage()).matches(".oo.")
                                 .containsPattern("oo.");
  // or even better thanks to Rolland Illig suggestion
  assertThat(thrown).hasMessageMatching(".oo.");

}

请注意,通过使用catchThrowableOfType,您不必再检查捕获的异常是否属于预期类型。

关于java - AssertJ:使用 String.format 生成的消息测试异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52819393/

相关文章:

java - 如何在java中将文本内容规范化为UTF 8

maven - 使用 Maven 命令运行 Junit Suite

java - AssertThat 错误 : Cannot access path (java. nio.file.Path 未找到)

java - cucumber.runtime.CucumberException : No backends were found. 请确保您的 CLASSPATH 上有后端模块

java - 使用 AssertJ 验证列表项是否具有相同的值,但不是相同的实例

java - 如何开始 : testing Java Swing GUI with AssertJ Swing

java - 通过连接点进行 spring 方面的单元测试用例?

java - 获取 webapp 上下文的 URL(基本 URL)

java - maven中没有main.java的包名

java - PageObjectModel 与 ExcelBased Selenium 框架