Class SoftAssertions
- All Implemented Interfaces:
AfterAssertionErrorCollected
,AssertionErrorCollector
,InstanceOfAssertFactories
,Java6StandardSoftAssertionsProvider
,SoftAssertionsProvider
,StandardSoftAssertionsProvider
- Direct Known Subclasses:
AutoCloseableSoftAssertions
Suppose we have a test case and in it we'd like to make numerous assertions. In this case, we're hosting a dinner party and we want to ensure not only that all our guests survive but also that nothing in the mansion has been unduly disturbed:
@Test
public void host_dinner_party_where_nobody_dies() {
Mansion mansion = new Mansion();
mansion.hostPotentiallyMurderousDinnerParty();
assertThat(mansion.guests()).as("Living Guests").isEqualTo(7);
assertThat(mansion.kitchen()).as("Kitchen").isEqualTo("clean");
assertThat(mansion.library()).as("Library").isEqualTo("clean");
assertThat(mansion.revolverAmmo()).as("Revolver Ammo").isEqualTo(6);
assertThat(mansion.candlestick()).as("Candlestick").isEqualTo("pristine");
assertThat(mansion.colonel()).as("Colonel").isEqualTo("well kempt");
assertThat(mansion.professor()).as("Professor").isEqualTo("well kempt");
}
After running the test, JUnit provides us with the following exception message:
org.junit.ComparisonFailure: [Living Guests] expected:<[7]> but was:<[6]>
Oh no! A guest has been murdered! But where, how, and by whom?
Unfortunately frameworks like JUnit halt the test upon the first failed assertion. Therefore, to collect more evidence, we'll have to rerun the test (perhaps after attaching a debugger or modifying the test to skip past the first assertion). Given that hosting dinner parties takes a long time, this seems rather inefficient.
Instead let's change the test so that at its completion we get the result of all assertions at once. We can do that
by using a SoftAssertions instance instead of the static methods on Assertions
as follows:
@Test
public void host_dinner_party_where_nobody_dies() {
Mansion mansion = new Mansion();
mansion.hostPotentiallyMurderousDinnerParty();
SoftAssertions softly = new SoftAssertions();
softly.assertThat(mansion.guests()).as("Living Guests").isEqualTo(7);
softly.assertThat(mansion.kitchen()).as("Kitchen").isEqualTo("clean");
softly.assertThat(mansion.library()).as("Library").isEqualTo("clean");
softly.assertThat(mansion.revolverAmmo()).as("Revolver Ammo").isEqualTo(6);
softly.assertThat(mansion.candlestick()).as("Candlestick").isEqualTo("pristine");
softly.assertThat(mansion.colonel()).as("Colonel").isEqualTo("well kempt");
softly.assertThat(mansion.professor()).as("Professor").isEqualTo("well kempt");
softly.assertAll();
}
Now upon running the test our JUnit exception message is far more detailed:
org.assertj.core.api.SoftAssertionError: The following 4 assertions failed:
1) [Living Guests] expected:<[7]> but was:<[6]>
2) [Library] expected:<'[clean]'> but was:<'[messy]'>
3) [Candlestick] expected:<'[pristine]'> but was:<'[bent]'>
4) [Professor] expected:<'[well kempt]'> but was:<'[bloodied and disheveled]'>
Aha! It appears that perhaps the Professor used the candlestick to perform the nefarious deed in the library. We should let the police take it from here.
You can also use the static method assertSoftly. the assertAll method will be called automatically after the lambda function completes.
@Test
public void host_dinner_party_where_nobody_dies() {
Mansion mansion = new Mansion();
mansion.hostPotentiallyMurderousDinnerParty();
SoftAssertions.assertSoftly(softly -> {
softly.assertThat(mansion.guests()).as("Living Guests").isEqualTo(7);
softly.assertThat(mansion.kitchen()).as("Kitchen").isEqualTo("clean");
softly.assertThat(mansion.library()).as("Library").isEqualTo("clean");
softly.assertThat(mansion.revolverAmmo()).as("Revolver Ammo").isEqualTo(6);
softly.assertThat(mansion.candlestick()).as("Candlestick").isEqualTo("pristine");
softly.assertThat(mansion.colonel()).as("Colonel").isEqualTo("well kempt");
softly.assertThat(mansion.professor()).as("Professor").isEqualTo("well kempt");
});
}
You can also compose several soft assertions together using the SoftAssertionsProvider.assertAlso(AssertionErrorCollector)
method
public SoftAssertions check_kitchen() {
SoftAssertions softly = new SoftAssertions();
softly.assertThat(mansion.kitchen()).as("Kitchen").isEqualTo("clean");
return softly;
}
public SoftAssertions check_library() {
SoftAssertions softly = new SoftAssertions();
softly.assertThat(mansion.library()).as("Library").isEqualTo("clean");
return softly;
}
@Test
public void host_dinner_party_where_nobody_dies() {
Mansion mansion = new Mansion();
mansion.hostPotentiallyMurderousDinnerParty();
softly.assertThat(mansion.guests()).as("Living Guests").isEqualTo(7);
softly.assertThat(mansion.revolverAmmo()).as("Revolver Ammo").isEqualTo(6);
softly.assertThat(mansion.candlestick()).as("Candlestick").isEqualTo("pristine");
softly.assertThat(mansion.colonel()).as("Colonel").isEqualTo("well kempt");
softly.assertThat(mansion.professor()).as("Professor").isEqualTo("well kempt");
SoftAssertions kitchen = check_kitchen();
softly.assertAlso(kitchen);
SoftAssertions library = check_library();
softly.assertAlso(library);
softly.assertAll();
}
SoftAssertions works by providing you with proxies of the AssertJ assertion objects (those created by
Assertions
#assertThat...) whose assertion failures are caught and stored. Only when you call
SoftAssertionsProvider.assertAll()
will a SoftAssertionError
be thrown containing the error messages of those
previously caught assertion failures.
Note that because SoftAssertions is stateful you should use a new instance of SoftAssertions per test method. Also,
if you forget to call assertAll() at the end of your test, the test will pass even if any assertion
objects threw exceptions (because they're proxied, remember?). So don't forget. You might use
JUnitSoftAssertions
or AutoCloseableSoftAssertions
to get assertAll() to be called automatically.
It is recommended to use Descriptable.as(String, Object...)
so that the multiple failed assertions can be
easily distinguished from one another.
- Author:
- Brian Laframboise
- See Also:
-
Nested Class Summary
Nested classes/interfaces inherited from interface org.assertj.core.api.SoftAssertionsProvider
SoftAssertionsProvider.ThrowingRunnable
-
Field Summary
Fields inherited from interface org.assertj.core.api.InstanceOfAssertFactories
ARRAY, ARRAY_2D, ATOMIC_BOOLEAN, ATOMIC_INTEGER, ATOMIC_INTEGER_ARRAY, ATOMIC_INTEGER_FIELD_UPDATER, ATOMIC_LONG, ATOMIC_LONG_ARRAY, ATOMIC_LONG_FIELD_UPDATER, ATOMIC_MARKABLE_REFERENCE, ATOMIC_REFERENCE, ATOMIC_REFERENCE_ARRAY, ATOMIC_REFERENCE_FIELD_UPDATER, ATOMIC_STAMPED_REFERENCE, BIG_DECIMAL, BIG_INTEGER, BOOLEAN, BOOLEAN_2D_ARRAY, BOOLEAN_ARRAY, BYTE, BYTE_2D_ARRAY, BYTE_ARRAY, CHAR_2D_ARRAY, CHAR_ARRAY, CHAR_SEQUENCE, CHARACTER, CLASS, COLLECTION, COMPLETABLE_FUTURE, COMPLETION_STAGE, DATE, DOUBLE, DOUBLE_2D_ARRAY, DOUBLE_ARRAY, DOUBLE_PREDICATE, DOUBLE_STREAM, DURATION, FILE, FLOAT, FLOAT_2D_ARRAY, FLOAT_ARRAY, FUTURE, INPUT_STREAM, INSTANT, INT_2D_ARRAY, INT_ARRAY, INT_PREDICATE, INT_STREAM, INTEGER, ITERABLE, ITERATOR, LIST, LOCAL_DATE, LOCAL_DATE_TIME, LOCAL_TIME, LONG, LONG_2D_ARRAY, LONG_ADDER, LONG_ARRAY, LONG_PREDICATE, LONG_STREAM, MAP, MATCHER, OFFSET_DATE_TIME, OFFSET_TIME, OPTIONAL, OPTIONAL_DOUBLE, OPTIONAL_INT, OPTIONAL_LONG, PATH, PERIOD, PREDICATE, SHORT, SHORT_2D_ARRAY, SHORT_ARRAY, SPLITERATOR, STREAM, STRING, STRING_BUFFER, STRING_BUILDER, THROWABLE, URI_TYPE, URL_TYPE, ZONED_DATE_TIME
-
Constructor Summary
-
Method Summary
Modifier and TypeMethodDescriptionstatic void
assertSoftly
(Consumer<SoftAssertions> softly) Convenience method for callingSoftAssertionsProvider.assertSoftly(java.lang.Class<S>, java.util.function.Consumer<S>)
for these assertion types.Methods inherited from class org.assertj.core.api.AbstractSoftAssertions
assertAll, assertAll, errorsCollected, fail, fail, fail, failBecauseExceptionWasNotThrown, proxy, shouldHaveThrown
Methods inherited from class org.assertj.core.api.DefaultAssertionErrorCollector
assertionErrorsCollected, collectAssertionError, decorateErrorsCollected, getDelegate, setAfterAssertionErrorCollected, setDelegate, succeeded, wasSuccess
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
Methods inherited from interface org.assertj.core.api.AssertionErrorCollector
assertionErrorsCollected, collectAssertionError, getDelegate, onAssertionErrorCollected, setDelegate, succeeded, wasSuccess
Methods inherited from interface org.assertj.core.api.Java6StandardSoftAssertionsProvider
assertThat, assertThat, assertThat, assertThat, assertThat, assertThat, assertThat, assertThat, assertThat, assertThat, assertThat, assertThat, assertThat, assertThat, assertThat, assertThat, assertThat, assertThat, assertThat, assertThat, assertThat, assertThat, assertThat, assertThat, assertThat, assertThat, assertThat, assertThat, assertThat, assertThat, assertThat, assertThat, assertThat, assertThat, assertThat, assertThat, assertThat, assertThat, assertThat, assertThat, assertThat, assertThat, assertThat, assertThat, assertThat, assertThat, assertThat, assertThat, assertThat, assertThat, assertThat, assertThat, assertThat, assertThat, assertThat, assertThat, assertThat, assertThat, assertThat, assertThat, assertThat, assertThat, assertThat, assertThat, assertThat, assertThatCharSequence, assertThatCode, assertThatCollection, assertThatComparable, assertThatException, assertThatExceptionOfType, assertThatIllegalArgumentException, assertThatIllegalStateException, assertThatIndexOutOfBoundsException, assertThatIOException, assertThatIterable, assertThatIterator, assertThatList, assertThatNullPointerException, assertThatObject, assertThatReflectiveOperationException, assertThatRuntimeException, assertThatThrownBy, assertThatThrownBy
Methods inherited from interface org.assertj.core.api.SoftAssertionsProvider
assertAll, assertAlso, check, proxy
Methods inherited from interface org.assertj.core.api.StandardSoftAssertionsProvider
assertThat, assertThat, assertThat, assertThat, assertThat, assertThat, assertThat, assertThat, assertThat, assertThat, assertThat, assertThat, assertThat, assertThat, assertThat, assertThat, assertThat, assertThat, assertThat, assertThat, assertThat, assertThat, assertThat, assertThat, assertThat, assertThat, assertThat, assertThatPath, assertThatPredicate, assertThatStream
-
Constructor Details
-
SoftAssertions
public SoftAssertions()
-
-
Method Details
-
assertSoftly
Convenience method for callingSoftAssertionsProvider.assertSoftly(java.lang.Class<S>, java.util.function.Consumer<S>)
for these assertion types. Equivalent toSoftAssertion.assertSoftly(SoftAssertions.class, softly)
.- Parameters:
softly
- the Consumer containing the code that will make the soft assertions. Takes one parameter (the SoftAssertions instance used to make the assertions).- Throws:
org.opentest4j.MultipleFailuresError
- if possible or SoftAssertionError if any proxied assertion objects threw anAssertionError
-