软断言导致后续测试失败时抛出的异常
Exceptions thrown while soft asserting fail the subsequent tests
根据标题,我正在尝试 运行 循环测试用例。为了能够计算失败断言的数量,我希望如果 AssertJ 试图断言方法调用的返回值,它应该 softly 失败一次迭代并继续.否则,它违背了软断言的目的。这是一个说明这一点的片段:
public static void main(String[] args) {
SoftAssertions softAssertions = new SoftAssertions();
softAssertions.assertThat(throwException(10)).isTrue();
softAssertions.assertThat(throwException(10)).isTrue();
softAssertions.assertThat(throwException(1)).isTrue();
softAssertions.assertAll();
}
private static boolean throwException(int stuff){
if(stuff == 1){
throw new RuntimeException();
}
return true;
}
输出:
Exception in thread "main" java.lang.RuntimeException
at eLCMUpdate.throwException(MyClass.java:101)
at eLCMUpdate.main(MyClass.java:95)
我在这里遗漏了一些东西。我做错了什么吗?
根据我的理解,软断言适用于布尔值而不适用于异常。
另外:如果你在调用softAssertions.assertAll()
之前抛出异常,显然这个方法也永远不会被执行。这实际上是您报告的行为的原因。
只需尝试调试您的代码,您就会发现 softAssertions.assertAll()
从未被调用。
如果您将代码更改为:
,软断言将正常工作
@Test
void soft_assertions() {
SoftAssertions softAssertions = new SoftAssertions();
softAssertions.assertThat(checkCondition(10)).isTrue();
softAssertions.assertThat(checkCondition(10)).isTrue();
softAssertions.assertThat(checkCondition(1)).isTrue();
softAssertions.assertThat(checkCondition(2)).isTrue();
softAssertions.assertThat(checkCondition(20)).isTrue();
softAssertions.assertAll();
}
private static boolean checkCondition(int stuff){
if(stuff == 1 || stuff == 2){
return false;
}
return true;
}
这将输出多个断言的结果,并且不会停止对第一个失败断言的评估。
输出:
org.assertj.core.api.SoftAssertionError:
The following 2 assertions failed:
1)
Expecting:
<false>
to be equal to:
<true>
but was not.
at JsonStewardshipCustomerConversionTest.soft_assertions(JsonStewardshipCustomerConversionTest.java:301)
2)
Expecting:
<false>
to be equal to:
<true>
but was not.
at JsonStewardshipCustomerConversionTest.soft_assertions(JsonStewardshipCustomerConversionTest.java:302)
更新
SoftAssertion 似乎不符合您的目的。
我建议您改用 JUnit 5 assertAll
。根据我的测试,它会评估 assertAll
块中的所有条件,并且也会在异常情况下幸存下来。这里的问题是您需要 JUnit 5,它可能尚未被广泛采用。
这是一个布尔条件失败和异常的示例。两者都在控制台中报告。
@Test
void soft_assertions() {
assertAll("Check condition",
() -> assertThat(checkCondition(9)).isTrue(),
() -> assertThat(checkCondition(10)).isTrue(),
() -> assertThat(checkCondition(11)).isTrue(),
() -> assertThat(checkCondition(2)).isTrue(), // Throws exception
() -> assertThat(checkCondition(3)).isFalse(), // fails
() -> assertThrows(IllegalArgumentException.class, () -> {
checkCondition(1);
})
);
}
private static boolean checkCondition(int stuff) {
if (stuff == 1 || stuff == 2) {
throw new IllegalArgumentException();
}
return true;
}
您将在输出中看到:
org.opentest4j.MultipleFailuresError: Check condition (2 failures)
<no message> in java.lang.IllegalArgumentException
Expecting:
<true>
to be equal to:
<false>
but was not.
代码softAssertions.assertThat(throwException(10)).isTrue();
中的问题是,如果抛出异常,则根本不会执行assertThat
。
您需要对传入的代码进行惰性计算 assertThat
,您可以使用 AssertJ assertThatCode
执行此操作,如下所示:
final SoftAssertions softAssertions = new SoftAssertions();
softAssertions.assertThatCode(() -> throwException(10)).doesNotThrowAnyException();
softAssertions.assertThatCode(() -> throwException(1)).isInstanceOf(RuntimeException.class);
softAssertions.assertAll();
根据标题,我正在尝试 运行 循环测试用例。为了能够计算失败断言的数量,我希望如果 AssertJ 试图断言方法调用的返回值,它应该 softly 失败一次迭代并继续.否则,它违背了软断言的目的。这是一个说明这一点的片段:
public static void main(String[] args) {
SoftAssertions softAssertions = new SoftAssertions();
softAssertions.assertThat(throwException(10)).isTrue();
softAssertions.assertThat(throwException(10)).isTrue();
softAssertions.assertThat(throwException(1)).isTrue();
softAssertions.assertAll();
}
private static boolean throwException(int stuff){
if(stuff == 1){
throw new RuntimeException();
}
return true;
}
输出:
Exception in thread "main" java.lang.RuntimeException
at eLCMUpdate.throwException(MyClass.java:101)
at eLCMUpdate.main(MyClass.java:95)
我在这里遗漏了一些东西。我做错了什么吗?
根据我的理解,软断言适用于布尔值而不适用于异常。
另外:如果你在调用softAssertions.assertAll()
之前抛出异常,显然这个方法也永远不会被执行。这实际上是您报告的行为的原因。
只需尝试调试您的代码,您就会发现 softAssertions.assertAll()
从未被调用。
如果您将代码更改为:
,软断言将正常工作@Test
void soft_assertions() {
SoftAssertions softAssertions = new SoftAssertions();
softAssertions.assertThat(checkCondition(10)).isTrue();
softAssertions.assertThat(checkCondition(10)).isTrue();
softAssertions.assertThat(checkCondition(1)).isTrue();
softAssertions.assertThat(checkCondition(2)).isTrue();
softAssertions.assertThat(checkCondition(20)).isTrue();
softAssertions.assertAll();
}
private static boolean checkCondition(int stuff){
if(stuff == 1 || stuff == 2){
return false;
}
return true;
}
这将输出多个断言的结果,并且不会停止对第一个失败断言的评估。
输出:
org.assertj.core.api.SoftAssertionError:
The following 2 assertions failed:
1)
Expecting:
<false>
to be equal to:
<true>
but was not.
at JsonStewardshipCustomerConversionTest.soft_assertions(JsonStewardshipCustomerConversionTest.java:301)
2)
Expecting:
<false>
to be equal to:
<true>
but was not.
at JsonStewardshipCustomerConversionTest.soft_assertions(JsonStewardshipCustomerConversionTest.java:302)
更新
SoftAssertion 似乎不符合您的目的。
我建议您改用 JUnit 5 assertAll
。根据我的测试,它会评估 assertAll
块中的所有条件,并且也会在异常情况下幸存下来。这里的问题是您需要 JUnit 5,它可能尚未被广泛采用。
这是一个布尔条件失败和异常的示例。两者都在控制台中报告。
@Test
void soft_assertions() {
assertAll("Check condition",
() -> assertThat(checkCondition(9)).isTrue(),
() -> assertThat(checkCondition(10)).isTrue(),
() -> assertThat(checkCondition(11)).isTrue(),
() -> assertThat(checkCondition(2)).isTrue(), // Throws exception
() -> assertThat(checkCondition(3)).isFalse(), // fails
() -> assertThrows(IllegalArgumentException.class, () -> {
checkCondition(1);
})
);
}
private static boolean checkCondition(int stuff) {
if (stuff == 1 || stuff == 2) {
throw new IllegalArgumentException();
}
return true;
}
您将在输出中看到:
org.opentest4j.MultipleFailuresError: Check condition (2 failures)
<no message> in java.lang.IllegalArgumentException
Expecting:
<true>
to be equal to:
<false>
but was not.
代码softAssertions.assertThat(throwException(10)).isTrue();
中的问题是,如果抛出异常,则根本不会执行assertThat
。
您需要对传入的代码进行惰性计算 assertThat
,您可以使用 AssertJ assertThatCode
执行此操作,如下所示:
final SoftAssertions softAssertions = new SoftAssertions();
softAssertions.assertThatCode(() -> throwException(10)).doesNotThrowAnyException();
softAssertions.assertThatCode(() -> throwException(1)).isInstanceOf(RuntimeException.class);
softAssertions.assertAll();