软断言导致后续测试失败时抛出的异常

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();