Do you think this test passes?
@Test
void mystery() {
var softly = new SoftAssertions();
softly.assertThat("robot").isEqualTo("izzy");
softly.assertThat(126).isLessThanOrEqualTo(125);
}
It does! Since softly is never told that it is done, the test does not fail. I’ve been using the approach of calling assertAll() to get my tests to fail:
@Test
void callingAssertAll() {
var softly = new SoftAssertions();
softly.assertThat("robot").isEqualTo("izzy");
softly.assertThat(126).isLessThanOrEqualTo(125);
softly.assertAll();
}
I learned there are a few other approaches today. One is using an autocloseable version. This one is great if you are using a local variable:
@Test
void autoclosable() {
try (var softly = new AutoCloseableSoftAssertions()) {
softly.assertThat("robot").isEqualTo("izzy");
softly.assertThat(126).isLessThanOrEqualTo(125);
}
}
Alternatively, you can use the lambda version. I like the autoclosable one better as it doesn’t encourage cramming stuff in a lambda. I could call another method inside assertSoftly with the actual asserts but that doesn’t seem better than using try with resources.
@Test
void lambda() {
SoftAssertions.assertSoftly(s -> {
s.assertThat("robot").isEqualTo("izzy");
s.assertThat(126).isLessThanOrEqualTo(125);
});
}
There’s another way with an extension (that comes with asserj-core). I like this approach as it uses an instance variable and doesn’t require figuring out a place to call assertAll
@ExtendWith(SoftAssertionsExtension.class)
class SoftAssertionsExtensionTest {
@InjectSoftAssertions
SoftAssertions softly;
@Test
void field() {
softly.assertThat("robot").isEqualTo("izzy");
softly.assertThat(126).isLessThanOrEqualTo(125);
}
}
The same can be done with a method. It’s nice to have choices!
@ExtendWith(SoftAssertionsExtension.class)
class SoftAssertionsExtensionTest {
@Test
void parameter(SoftAssertions softly) {
softly.assertThat("robot").isEqualTo("izzy");
softly.assertThat(126).isLessThanOrEqualTo(125);
}
}