Search code examples
javajunit5

JUnit5 assertAll


The code is as shown below. I want it go test all the elements of keyNames. But, it stops if any test fails and doesn't iterate through all array elements. My understanding being, in assertAll all assertions are executed, and any failures should be reported together.

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

Solution

  • The javadoc of Assertions.assertAll() states :

    Asserts that all supplied executables do not throw exceptions.

    And actually you provide a single Executable in assertAll() at each iteration.
    So a failure in any iteration of the loop terminates the test execution.

    In fact you invoke multiple times assertAll() by requesting at most a single assertion at each time :

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

    What you want is doing the reverse : invoking assertAll() by passing multiple Executable instances performing the required assertions.

    So you could collect them in a List with a classic loop and pass it in this way : assertAll(list.stream()) or creating a Stream<Executable> without any collect and pass it directly such as assertAll(stream).

    Here is a version with Stream (not tested at all) but you should get the idea :

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