JUnit5 assertAll

JUnit5 assertAll

代码如下图。我希望它去测试 keyNames 的所有元素。 但是,如果任何测试失败并且不会遍历所有数组元素,它就会停止。 我的理解是,在 assertAll 中执行所有断言,并且应该一起报告任何失败。

感谢您的宝贵时间和帮助。

private void validateData(SearchHit searchResult, String [] line){

        for(Integer key : keyNames){
            String expectedValue = getExpectedValue(line, key);
            String elementName = mappingProperties.getProperty(key.toString());

            if (elementName != null && elementName.contains(HEADER)){
                assertAll(
                        () -> assumingThat((expectedValue != null && expectedValue.length() > 0),
                                () -> {
                                        String actualValue = testHelper.getHeaderData(searchResult, elementName);

                                        if(expectedValue != null) {
                                            assertEquals(expectedValue, actualValue, " ###Element Name -> " + elementName +" :  Excepted Value ### " + expectedValue + " ### Actual Value ###" + actualValue);
                                        }
                                      }
                                 )
                );

            }

        }
    }

Assertions.assertAll() 的 javadoc 指出:

Asserts that all supplied executables do not throw exceptions.

实际上,您在每次迭代时在 assertAll() 中提供了一个 Executable
因此,循环的任何迭代失败都会终止测试执行。

实际上,您通过每次最多请求一个断言来调用多次 assertAll()

if(expectedValue != null) {
    assertEquals(expectedValue, actualValue, " ###Element Name -> " + elementName +" :  Excepted Value ### " + expectedValue + " ### Actual Value ###" + actualValue);
}

您想要的是相反的操作:通过传递多个 Executable 实例来执行所需的断言来调用 assertAll()

因此您可以使用经典循环将它们收集在 List 中并以这种方式传递: assertAll(list.stream()) 或创建一个 Stream<Executable> 没有任何收集并直接传递它,例如 assertAll(stream)

这是一个带有 Stream 的版本(根本没有测试过),但你应该明白了:

Stream<Executable> executables = 
keyNames.stream()
        .map(key-> 
               // create an executable for each value of the streamed list
                ()-> {
                        String expectedValue = getExpectedValue(line, key);
                        String elementName = mappingProperties.getProperty(key.toString());

                        if (elementName != null && elementName.contains(HEADER)){
                             assumingThat((expectedValue != null && expectedValue.length() > 0),
                                            () -> {                                             
                                                    String actualValue = testHelper.getHeaderData(searchResult, elementName);
                                                    if(expectedValue != null) {
                                                        assertEquals(expectedValue, actualValue, " ###Element Name -> " + elementName +" :  Excepted Value ### " + expectedValue + " ### Actual Value ###" + actualValue);
                                                    }                                                                            

                                            }
                            );

                        }

                    }
            );
Assertions.assertAll(executables);

assertAll() 将传递给 assertAll() 的调用的所有断言和错误分组。它不会 对测试方法期间发生的所有调用的断言进行分组。

在您发布的代码中,您将一个断言 lambda 传递给 assertAll()。它不会跨多个键对错误进行分组,因为每个 key 都有一个单独的 assertAll().

调用

为确保您单独测试集合中的所有值,请查看 parameterized tests

如@user31601, parameterized tests (see documentation所示)自动独立测试所有案例。

这导致了以下(更简单的)代码:

@ParameterizedTest
@MethodSource("getKeys")
void testKey(String key) { 
    String elementName = mappingProperties.getProperty(key.toString());
    assumeTrue(elementName != null);
    assumeTrue(elementName.contains(HEADER));

    String expectedValue = getExpectedValue(line, key);
    assumeTrue(expectedValue != null);
    assumeTrue(expectedValue.length() > 0);

    String actualValue = testHelper.getHeaderData(searchResult, elementName);
    String doc = String.format("name: %s, expected %s, actual %s", elementName, expectedValue, actualValue);
    assertEquals(expectedValue, actualValue, doc);
}

private static Stream<String> getKeys() {
    return keyNames.stream()
}