Here's a code:
package com.example;
import org.assertj.core.api.SoftAssertions;
import org.junit.jupiter.api.Test;
import java.util.List;
public class SoftAssertionsTest {
@Test
void testSoftAssertions() {
List.of(1, 2, 3).forEach(element ->
SoftAssertions.assertSoftly(softAssertions ->
softAssertions.fail("Ka-boom! Index: " + element)));
}
}
I expected something along the lines of:
Ka-boom! Index: 1
Ka-boom! Index: 2
Ka-boom! Index: 3
Instead, AssertJ quit after the very first assertion error:
org.assertj.core.error.AssertJMultipleFailuresError:
Multiple Failures (1 failure)
-- failure 1 --Ka-boom! Index: 1
at SoftAssertionsTest.lambda$testSoftAssertions$0(SoftAssertionsTest.java:13)
at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:77)
at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.base/java.lang.reflect.Constructor.newInstanceWithCaller(Constructor.java:499)
at by.afinny.credit.unit.repository.SoftAssertionsTest.lambda$testSoftAssertions$1(SoftAssertionsTest.java:12)
at java.base/java.lang.Iterable.forEach(Iterable.java:75)
Why? Is there some way to manually trigger soft assertion errors in AssertJ?
In case you're wondering why I need that, imagine I have a list that expect to be empty, but if it's not, I want to assert on each element with dynamic fail messages (real case)
SoftAssertions.assertSoftlyfails if any of the inner assertions failed (the assertions inside the lambda). You are callingassertSoftly3 times with only a single inner assertion.Your code is equivalent to:
But you want:
Thus, you need to move the loop into your
assertSoftlycall: