Top Description Fields Constructors Methods
org.assertj.core.api

public Class BDDSoftAssertions

extends AbstractSoftAssertions
implements BDDSoftAssertionsProvider
Class Inheritance
All Implemented Interfaces
org.assertj.core.api.BDDSoftAssertionsProvider, org.assertj.core.api.Java6BDDSoftAssertionsProvider, org.assertj.core.api.SoftAssertionsProvider, org.assertj.core.api.AssertionErrorCollector, org.assertj.core.api.AfterAssertionErrorCollected
Known Direct Subclasses
org.assertj.core.api.AutoCloseableBDDSoftAssertions
Imports
java.util.function.Consumer, org.opentest4j.MultipleFailuresError

Suppose we have a test case and in it we'd like to make numerous BDD 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();
  then(mansion.guests()).as("Living Guests").isEqualTo(7);
  then(mansion.kitchen()).as("Kitchen").isEqualTo("clean");
  then(mansion.library()).as("Library").isEqualTo("clean");
  then(mansion.revolverAmmo()).as("Revolver Ammo").isEqualTo(6);
  then(mansion.candlestick()).as("Candlestick").isEqualTo("pristine");
  then(mansion.colonel()).as("Colonel").isEqualTo("well kempt");
  then(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 BDDSoftAssertions instance instead of the static methods on BDDAssertions as follows:

 @Test
public void host_dinner_party_where_nobody_dies() {
  Mansion mansion = new Mansion();
  mansion.hostPotentiallyMurderousDinnerParty();
  BDDSoftAssertions softly = new BDDSoftAssertions();
  softly.then(mansion.guests()).as("Living Guests").isEqualTo(7);
  softly.then(mansion.kitchen()).as("Kitchen").isEqualTo("clean");
  softly.then(mansion.library()).as("Library").isEqualTo("clean");
  softly.then(mansion.revolverAmmo()).as("Revolver Ammo").isEqualTo(6);
  softly.then(mansion.candlestick()).as("Candlestick").isEqualTo("pristine");
  softly.then(mansion.colonel()).as("Colonel").isEqualTo("well kempt");
  softly.then(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.

BDDSoftAssertions works by providing you with proxies of the AssertJ assertion objects (those created by BDDAssertions#then...) whose assertion failures are caught and stored. Only when you call BDDSoftAssertions#assertAll() will a SoftAssertionError be thrown containing the error messages of those previously caught assertion failures.

Note that because BDDSoftAssertions is stateful you should use a new instance of BDDSoftAssertions 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 JUnitBDDSoftAssertions or AutoCloseableBDDSoftAssertions to get assertAll() to be called automatically.

It is recommended to use AbstractAssert#as(String, Object...) so that the multiple failed assertions can be easily distinguished from one another.

Author
Brian Laframboise
See Also
Reinventing Assertions (inspired this feature)

Field Summary

Inherited from org.assertj.core.api.AbstractSoftAssertions:
proxies

Constructor Summary

AccessConstructor and Description
public

Method Summary

Modifier and TypeMethod and Description
public static void
thenSoftly(Consumer<BDDSoftAssertions>
the Consumer containing the code that will make the soft assertions. Takes one parameter (the actual BDDSoftAssertions instance used to make the assertions).
softly
)

Convenience method for calling SoftAssertionsProvider#assertSoftly for these assertion types.

Inherited from org.assertj.core.api.AbstractSoftAssertions:
assertAllassertAllerrorsCollectedfailfailfailfailfailfailBecauseExceptionWasNotThrownproxyshouldHaveThrown

Constructor Detail

BDDSoftAssertionsback to summary
public BDDSoftAssertions()

Method Detail

thenSoftlyback to summary
public static void thenSoftly(Consumer<BDDSoftAssertions> softly)

Convenience method for calling SoftAssertionsProvider#assertSoftly for these assertion types. Equivalent to SoftAssertion.assertSoftly(BDDSoftAssertions.class, softly).

Parameters
softly:Consumer<BDDSoftAssertions>

the Consumer containing the code that will make the soft assertions. Takes one parameter (the actual BDDSoftAssertions instance used to make the assertions).

Exceptions
MultipleFailuresError:
if possible or SoftAssertionError if any proxied assertion objects threw an AssertionError
Since
3.16.0