Java AssertJ:使用String.format生成的消息测试异常
我想知道当使用String.format()生成消息时,是否有一种干净完整的方法来断言附加到抛出异常的消息。例如,一个类,如:Java AssertJ:使用String.format生成的消息测试异常,java,junit,assertj,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) { t
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));
}
}
}
(为这个奇怪的例子感到抱歉,只是尽量让它简单)
现在,如果我在测试汽车,我会有这样一门课:
public class CarTest {
@Test
public void drive_test() {
Car car = new Car("Greased Lightning");
assertThatThrownBy(() -> car.drive())
.isInstanceOf(IllegalStateException.class)
.hasMessageContaining("???");
}
}
问题是,对消息进行断言的最佳方式是什么?在本例中,我可以分离出汽车名称的声明,然后自己使用字符串格式从汽车中获取静态字符串并在名称中进行格式化,但这似乎需要很多额外的代码,并且不能在很多实例中轻松使用(例如,当在运行时确定格式化字符串中的项目时)。我真正想做的是将错误消息字符串传递给hasMessageContaining
,让它忽略“%s”占位符并接受该位置的任何内容。有没有办法用assertJ对字符串进行正则表达式匹配?或者其他干净的方法
编辑:我还可以选择抛出异常,这些异常包含更容易测试的消息。一种解决方案是使用字符串连接,比如抛出新异常(静态错误消息+名称),然后测试消息是否包含第一部分,但这确实限制了消息的格式化能力,而且看起来不太干净。与常规字符串断言相比,异常消息断言受到限制。 您可以使用或断言,例如:
@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
您不必再检查捕获的异常是否属于预期类型。是否已存在hasMessageMatching
?我在AbstractThrowableAssertions中找到了它。我简直不敢相信,在一个设计如此精良的库中,你竟然会忘记这个函数,所以我仔细检查了一下。:)美丽的!谢谢