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.assertSoftly
fails if any of the inner assertions failed (the assertions inside the lambda). You are calling assertSoftly
3 times with only a single inner assertion.
Your code is equivalent to:
@Test
void testSoftAssertions() {
SoftAssertions.assertSoftly(soft -> soft.fail("Ka-boom! Index: 1"));
SoftAssertions.assertSoftly(soft -> soft.fail("Ka-boom! Index: 2"));
SoftAssertions.assertSoftly(soft -> soft.fail("Ka-boom! Index: 3"));
}
But you want:
@Test
void testSoftAssertions() {
SoftAssertions.assertSoftly(soft -> {
soft.fail("Ka-boom! Index: 1");
soft.fail("Ka-boom! Index: 2");
soft.fail("Ka-boom! Index: 3");
});
}
Thus, you need to move the loop into your assertSoftly
call:
@Test
void testSoftAssertions() {
SoftAssertions.assertSoftly(softAssertions -> {
List.of(1, 2, 3).forEach(element ->
softAssertions.fail("Ka-boom! Index: " + element));
});
}