dossani
dossani

Reputation: 1948

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

Upvotes: 2

Views: 5533

Answers (3)

avandeursen
avandeursen

Reputation: 8648

As indicated by @user31601, parameterized tests (see documentation) automatically test all cases independently.

This leads to the following (somewhat simpler) code):

@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()
}

Upvotes: 2

davidxxx
davidxxx

Reputation: 131316

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

Upvotes: 3

user31601
user31601

Reputation: 2610

assertAll() groups all assertions and errors that were passed to that invocation of assertAll(). It won't group assertions across all invocations that occur during the test method.

In the code you posted, you pass a single assertion lambda into assertAll(). It won't group errors across the multiple keys, as each key has a separate invocation of assertAll().

To ensure you separately test all values in a collection, take a look at parameterized tests.

Upvotes: 2

Related Questions