AssertJ Core latest releases

Release date : 2018-08-28

This release fixes Findbugs false positive on Assertions.fail methods by annotating them with @CanIgnoreReturnValue, thanks to Erhard Pointl and Glenn Sheasby for the fix.

Release date : 2018-08-15

Big thanks for all the contributors to this release:

  • Pascal Schumacher
  • Erhard Pointl
  • Stephan Windmüller
  • Roland Weisleder
  • Lars Hvile
  • Valeriy Vyrva
  • Günther Grill
  • Fr Jeremy Krieg
  • Drummond Dawson
  • Thomas Weißschuh
  • Alexandre Dutra
  • Add extracting(Function) to Object assertion that returns one value instead of a singleton list.
  • Favor throwing org.opentest4j.MultipleFailuresError over SoftAssertionError when soft assertions fails.
  • Clarify how Stream assertions are lazy initialized into List assertions.
  • Improve satisfies list assertion javadoc.
  • hasMessage fails with an AssertionFailedError allowing to compare actual and expected messages visually in IDEs.
  • Improve error message of Iterable allSatisfy assertion.
  • Make AssertJ compatible with Java 11. (Erhard Pointl)
  • Improve normalizeWhitespace and removeAllWhitespaces performance. (Pascal Schumacher)
  • A lot of internal improvements by Pascal Schumacher !
  • Javadoc improvements. (Pascal Schumacher)
  • allows fail() to be used where the java compiler expects a value like Optional.orElseGet(). (Thomas Weißschuh)
  • Better disambiguation of objects with the same toString() representation in error message. (Alexandre Dutra)
  • Fix if-else logic in PredicateAssert. (Lars Hvile)
  • Fix ClassCastException on SortedSet assertions when chained after extracting.
  • Fix missing OSGI Import-Package.
  • Fix isToday error message that inverted actual and expected dates. (Pascal Schumacher)
  • Remove spurious @CheckReturnValue from assertThatThrownBy/thenThrownBy. (Pascal Schumacher)
  • Fix parameter names in isStrictlyBetween that used the word inclusive instead of exclusive. (Günther Grill)
  • Fix missing OSGi Import-Package for dynamically loaded classes. (Fr Jeremy Krieg)
  • Fix compilation error containsAnyElementsOf by using bounded wildcard parameter. (Drummond Dawson)

Uses the given Function to extract a value from the object under test, the extracted value becoming the new object under test.

Note that since the value is extracted as an Object, only Object assertions can be chained after extracting.

Example:

// Create frodo, setting its name, age and Race
TolkienCharacter frodo = new TolkienCharacter("Frodo", 33, HOBBIT);

// let's extract and verify Frodo's name:
assertThat(frodo).extracting(TolkienCharacter::getName)
                 .isEqualTo("Frodo");
// The extracted value being a String, we would like to use String assertions 
// but we can't due to Java generics limitations. 
// The following assertion does NOT compile !
assertThat(frodo).extracting(TolkienCharacter::getName)
                 .startsWith("Fro");

This is a breaking change as previously extracting(TolkienCharacter::getName) would be resolved to extracting(Function... extractors) and return a (singleton) list.

// previous to 3.11, extracting returns a singleton list:
assertThat(frodo).extracting(TolkienCharacter::getName)
                 // use list assertion and not isEqualTo("Frodo") although 
                 // compiling it would fail as a list is expected
                 .containsExactly("Frodo");

Verifies that the actual CharSequence contains one or more whitespace characters according to Character.isWhitespace(char).

Examples:

assertThat(" ").containsWhitespaces();
assertThat("a b").containsWhitespaces();
assertThat(" c ").containsWhitespaces();

Verifies that the actual CharSequence is either null, empty or does not contain any whitespace characters according to Character.isWhitespace(char).

Examples:

assertThat("a").doesNotContainAnyWhitespaces();
assertThat("").doesNotContainAnyWhitespaces();
assertThat("ab").doesNotContainAnyWhitespaces();
String nullString = null;
assertThat(nullString).doesNotContainAnyWhitespaces();

Make AssertJ soft assertions usable with JUnit 5, this is equivalent of the Junit 4 soft assertions rule that calls assertAll for you.

Soft assertions examples:

public class SoftlyTest {
  
  @RegisterExtension
  public final JUnitJupiterSoftAssertions softly = new JUnitJupiterSoftAssertions();
  
  @Test
  public void soft_assertions() throws Exception {
    softly.assertThat(1).isEqualTo(2);
    softly.assertThat(Lists.newArrayList(1, 2)).containsOnly(1, 2);
  }
}

BDD Soft assertions examples:

public class SoftlyTest {

  @RegisterExtension
  public final JUnitJupiterBDDSoftAssertions softly = new JUnitJupiterBDDSoftAssertions();

  @Test
  public void soft_bdd_assertions() throws Exception {
    softly.then(1).isEqualTo(2);
    softly.then(Lists.newArrayList(1, 2)).containsOnly(1, 2);
  }
}

Verifies that the content of the actual InputStream is equal to the given String.

Examples:

InputStream inputStream = new ByteArrayInputStream("a".getBytes());  
assertThat(inputStream).hasContent("a");

Verifies that the Path/File/InputStream digest calculated with the specified algorithm is equal to the given value (either a String or a byte[]).

You can specify the message digest algorithm with MessageDigest or a String.

Examples:

// assume that assertj-core-2.9.0.jar was downloaded from https://repo1.maven.org/maven2
InputStream is = new FileInputStream(new File("assertj-core-2.9.0.jar"));

assertThat(is).hasDigest("SHA1", "5c5ae45b58f12023817abe492447cdc7912c1a2c")
              .hasDigest("MD5", "dcb3015cd28447644c810af352832c19")
              .hasDigest(MessageDigest.getInstance("SHA1"), "5c5ae45b58f12023817abe492447cdc7912c1a2c")
              .hasDigest(MessageDigest.getInstance("MD5"), "dcb3015cd28447644c810af352832c19")
              // full byte array omitted for brevety sake
              .hasDigest("SHA1", new byte[]{92, 90, ... })
              .hasDigest(MessageDigest.getInstance("SHA1"), new byte[]{92, 90, ... });

Add the comparison operator <, <=, > and >= to String assertions.

isLessThan examples:

assertThat("abc").isLessThan("bcd")
                 .isLessThan("b")
                 .isLessThan("abca")
                 .usingComparator(CASE_INSENSITIVE)
                 .isLessThan("BCD");

isLessThanOrEqualTo examples:

assertThat("abc").isLessThanOrEqualTo("bcd")
                 .isLessThanOrEqualTo("abc")
                 .isLessThanOrEqualTo("b")
                 .isLessThanOrEqualTo("abca")
                 .usingComparator(CASE_INSENSITIVE)
                 .isLessThanOrEqualTo("ABC");

isGreaterThan examples:

assertThat("xyz").isGreaterThan("abc")
                 .isGreaterThan("xy")
                 .isGreaterThan("ABC");
assertThat("XYZ").usingComparator(CASE_INSENSITIVE)
                 .isGreaterThan("abc");

isGreaterThanOrEqualTo examples:

assertThat("xyz").isGreaterThanOrEqualTo("abc")
                 .isGreaterThanOrEqualTo("xyz")
                 .isGreaterThanOrEqualTo("xy")
                 .isGreaterThanOrEqualTo("ABC");
assertThat("XYZ").usingComparator(CASE_INSENSITIVE)
                 .isGreaterThanOrEqualTo("abc");

isBetween verifies that the actual value is in [start, end] range (start and end included) according to String's compareTo method whereas isStrictlyBetween excludes start and end (]start, end[).

Examples:

// isBetween examples
assertThat("ab").isBetween("aa", "ac")
                .isBetween("ab", "ac")
                .isBetween("aa", "ab")
                .isBetween("ab", "ab")
                .isBetween("a", "c")
                .usingComparator(CASE_INSENSITIVE)
                .isBetween("AA", "AC");

// isStrictlyBetween examples
assertThat("ab").isStrictlyBetween("aa", "ac")
                .isStrictlyBetween("a", "c")
                .usingComparator(CASE_INSENSITIVE)
                .isStrictlyBetween("AA", "AC");

Verifies that the actual value satisfies the given condition, this is an alias of is(Condition) except for the wording of the error message that uses satisfies in place of is.

Example:

// Given
Condition<String> fairyTale = new Condition<>(s -> s.startsWith("Once upon a time"), "fairy tale start");
// When
String littleRedCap = "Once upon a time there was a dear little girl ...";
// Then
assertThat(littleRedCap).satisfies(fairyTale);

Filter the iterable under test keeping only elements matching the given assertions specified with a Consumer.

Example:

// Given
TolkienCharacter pippin = new TolkienCharacter("Pippin", 28, HOBBIT);
TolkienCharacter frodo = new TolkienCharacter("Frodo", 33, HOBBIT);
TolkienCharacter merry = new TolkienCharacter("Merry", 36, HOBBIT);
TolkienCharacter sam = new TolkienCharacter("Sam", 38, HOBBIT);
// When
List<TolkienCharacter> hobbits = list(frodo, sam, merry, pippin);
// Then
assertThat(hobbits).filteredOnAssertions(hobbit -> assertThat(hobbit.age).isLessThan(34))
                   .containsOnly(frodo, pippin);

Release date : 2018-05-12

This release improves soft assertions performance that decreased after migrating to byte buddy (the migration was necessary as cglib had non fixable issues). Although it is still slower than cglib based soft assertions, this version is much faster than 3.9.1. Thanks to Rafael Winterhalter and testn for their help.

The other contributors to this release are Pascal Schumacher, Andrey Kuzmin, Marcel Overdijk, Jacek Jackowiak, HugoHo0212, f4lco, Andrew Auclair, valery1707, Bernd Farka, nebehr, and Piotr Swiatowski. Thanks guys!

  • Propagate assertion context (description, overridden error message, representation and comparators):
    • after filtering iterables
    • after extracting, flatExtracting and extractingResultOf methods
    • on methods changing the object under test for soft assertions and assumptions
  • Exclude proxied class from SoftAssertions line number (in error stacktrace).
  • zipSatisfy now returns all zipped pairs not meeting the given requirements (instead of the first one).
  • Fix varargs warning on Map assertion extracting.
  • CompletableFuture representation now displays stacktrace when completed exceptionally. (Piotr Swiatowski)
  • Improve TypeComparators initialization resolving a performance degradation introduced in 3.9.1.
  • Allow overriding collected errors list modification.
  • (nebehr)
  • Close stream after lazy init of list assertions from stream. (f4lco)
  • Add org.assertj.core as Automatic-Module-Name in Manifest file. (Andrew Auclair)
  • Make constructors of ThrowableAssertAlternative and ThrowableTypeAssert public and ThrowableTypeAssert fields protected for better extensibility.
  • Internal code improvements. (Pascal Schumacher)
  • Javadoc improvements. (Pascal Schumacher), (valery1707)
  • README.md improvements. (HugoHo0212)
  • SortedSet assertions now honor the SortedSet comparator.
  • Fix Map assertion extracting that was limited to extracting values from String keys, it now accepts any Object keys.
  • Fix asList() that was not honoring the given description. (Andrey Kuzmin)
  • Fix soft assertions that did not handle correctly formatting error messages with double %.
  • Strongly typed navigation assertions were not supported after filteredOn operations.

Verifies that the actual list contains a value at given index that satisfies the given requirements.

Example:

List<TolkienCharacter> ringBearers = newArrayList(frodo, elrond, gandalf);

// this assertion will pass
assertThat(ringBearers).satisfies(ringBearer -> {
         assertThat(ringBearer.getAge()).isGreaterThan(200);
         assertThat(ringBearer.getRace()).isEqualTo(ELF);
     },
     atIndex(1));

// this assertion will fail
assertThat(ringBearers).satisfies(ringBearer -> {
         assertThat(ringBearer.getRace()).isEqualTo(ELF);
     },
     atIndex(0);

Verifies that no elements satisfy the given restrictions expressed as a Consumer.

Example:

// assume that all icelander in myIcelanderFriends are not from Brazil
 assertThat(myIcelanderFriends).noneSatisfy(friend -> {
                                  assertThat(friend.getCountry()).isEqualTo("Brazil");
                                });

Release date : 2018-02-21

This release is mainly a bugfix release, a notable highlight is the migration to byte buddy and a bunch of fixes related to soft assertions for methods that change the object under test like asString(), extracting, filteredOn, ...

Thanks to Pascal Schumacher, Erhard Pointl, Filip Hrisafov, Sebastien Arod, Simon Dudley, Gerard Szczepański, and Piotr Swiatowski for their contributions.

Special thanks to Rafael Winterhalter (byte buddy creator) for his help to migrate to byte buddy.

  • Add isEqualTo(long) to integer assertions. (Erhard Pointl)
  • Replace cglib with byte buddy. (Filip Hrisafov, Rafael Winterhalter)
  • Javadoc improvements. (Erhard Pointl, Pascal Schumacher)
  • Bump internal dependencies. (Pascal Schumacher, Erhard Pointl)
  • Remove unnecessary optional ASM dependency. (Pascal Schumacher)
  • Fix soft assertions and assumptions that were not properly supporting methods changing the object under test, including:
    • extracting, flatExtracting, extractingResultOf, filteredOn, map, flatMap
    • navigation assertions: size(), first(), element(index), last()
    • straight conversion: asString() and asList()
  • Fix reference to assertThat is ambiguous error introduced in 3.9.0 by moving assertThat(CompletionStage) to AssertionsForInterfaceTypes - #839.
  • Fix containsAnyOf that only worked with comparable elements - #1154.
  • Fix ClassNotFoundError on OSGI when using soft assertions - #1160. (Sebastien Arod)
  • Handle null correctly in ZonedDateTimeAssert isEqualTo and isNotEqualTo assertions - #1164. (Piotr Swiatowski)
  • Fix (hopefully) all warning like: A generic array of XXX is created for a varargs parameter - #1157.
  • Fix a regression in field by field recursive comparison where we stopped displaying an helpful error message - #1158.
  • Fix a NullPointerException in field by field recursive comparison when comparing null values - #1145. (Simon Dudley)
  • Fix BigDecimal.isBetween assertion that was failing when given the same start and end but with different scale - #1177.

Release date : 2018-01-02

This release includes all changes from AssertJ core 2.9.0 and adds the following that are Java 8 specific.

Thanks to Pascal Schumacher, Rudi Klassen, Kseniya Panasyuk, Filip Hrisafov, Michael Keppler, Jeremy Landis, Pontus Alexander, Jean-Noël Rouvignac, Alberto Scotto, Fr Jeremy Krieg, Mike Kobit, and Thibault Kruse for their contributions.

  • Add anyMatch to iterable/array assertions. (Jean-Noël Rouvignac)
  • Add noneMatch to iterable/array assertions. (Jean-Noël Rouvignac)
  • Add allSatisfy map assertion.
  • Add zipSatisfy assertion to check pairs built from two group of objects.
  • Add catchThrowableOfType to perform assertion on the caught throwable cast to the given type. (Fr Jeremy Krieg)
  • Allow performing Object assertion on the Optional value after calling get(). (Filip Hrisafov)
  • Add Assumptions for Java 8 types to skip tests when preconditions are not satisfied.
  • Allow to set a description for assertThatThrownBy.
  • Add a factory method to return a CompletableFuture assertion from a CompletionStage. (Thibault Kruse)
  • Allow to use a description after assertThatExceptionOfType like assertions. (Kseniya Panasyuk)
  • Align assertThat methods between Assertions and WithAssertions. (Filip Hrisafov)
  • Add missing thenCode BDD assertion.
  • Print stack trace information when doesNotThrowAnyException fails. (Mike Kobit)
  • Warn users that the Future state displayed in error messages might be different from the one at the time when the assertion was performed.
  • Javadoc improvements. (Pontus Alexander, Pascal Schumacher)
  • Contributor guide improvements. (Rudi Klassen)
  • Add openjdk8 build. (Jeremy Landis)
  • Maven build updates. (Jeremy Landis)
  • README.md improvements. (Michael Keppler)
  • ShouldContainCharSequenceOnlyOnce refactoring. (Alberto Scotto)
  • Fix a compiler error since 3.7.0 on assertThat(Stream) when given an upper bounded Stream.

Verifies whether any iterable/array elements match the provided Predicate.

Example:

Iterable<String> abcc = newArrayList("a", "b", "cc");

// assertion will pass
assertThat(abcc).anyMatch(s -> s.length() == 2);

// assertion will fail
assertThat(abcc).anyMatch(s -> s.length() > 2);

Note that you can achieve the same result with areNot(Condition)/doNotHave(Condition).

Verifies that no iterable/array elements match the provided Predicate.

Example:

Iterable<String> abcc = newArrayList("a", "b", "cc");

// assertion will pass
assertThat(abcc).noneMatch(s -> s.isEmpty());

// assertion will fail
assertThat(abcc).noneMatch(s -> s.length() == 2);

Note that you can achieve the same result with areAtLeastOne(Condition)/haveAtLeastOne(Condition).

Verifies that all the actual map entries satisfy the given entry requirements.

If the actual map is empty allSatisfy succeeds as there is nothing to check.

Example:

Map<TolkienCharacter, Ring> elvesRingBearers = new HashMap<>();
elvesRingBearers.put(galadriel, nenya);                       
elvesRingBearers.put(gandalf, narya);                         
elvesRingBearers.put(elrond, vilya);                          
                                                              
// this assertion succeeds
assertThat(elvesRingBearers).allSatisfy((character, ring) -> {
  assertThat(character.getRace()).isIn(ELF, MAIA);            
  assertThat(ring).isIn(nenya, narya, vilya);                 
});  

// this assertion fails as Gandalf is a maia and not an elf
assertThat(elvesRingBearers).allSatisfy((character, ring) -> {  
  assertThat(character.getRace()).isEqualTo(ELF);                
  assertThat(ring).isIn(nenya, narya, vilya);                            
});

Verifies that the zipped pairs of actual and expected elements, i.e: (actual 1st element, expected 1st element), (actual 2nd element, expected 2nd element), ... all satisfy the given requirements.

This assertion assumes that actual and expected have the same size but they can contain different types of elements making it handy to compare objects converted to another type, for example Domain and View/DTO objects.

Example:

List<Adress> addressModels = findGoodRestaurants();
List<AdressView> addressViews = convertToView(addressModels);

// compare addressViews and addressModels respective paired elements. 
assertThat(addressViews).zipSatisfy(addressModels, (AdressView view, Adress model) -> {
  assertThat(view.getZipcode() + ' ' + view.getCity()).isEqualTo(model.getCityLine());
  assertThat(view.getStreet()).isEqualTo(model.getStreet().toUpperCase());
});

catchThrowableOfType allows catching a Throwable of a specific type T. If no exception is thrown it returns null otherwise it checks that the caught Throwable is of type T and casts it making it convenient to perform subtype-specific assertions on the throwable of type T.

Example:

class CustomParseException extends Exception {
  int line;
  int column;
  
  public CustomParseException(String msg, int l, int c) {
    super(msg);
    line = l;
    column = c;
  }
}

CustomParseException e = catchThrowableOfType(() -> { throw new CustomParseException("boom!", 1, 5); },
                                              CustomParseException.class);
// assertions pass
assertThat(e).hasMessageContaining("boom");
assertThat(e.line).isEqualTo(1);
assertThat(e.column).isEqualTo(5);

 // succeeds as catchThrowableOfType returns null when the code does not thrown any exceptions 
assertThat(catchThrowableOfType(() -> {}, Exception.class)).isNull();

// fails as CustomParseException is not a RuntimeException
catchThrowableOfType(() -> { throw new CustomParseException("boom!", 1, 5); }, 
                     RuntimeException.class);

Verifies that the Optional under test is not null and not empty, then returns an Object assertion to allow chaining of (Object only) assertions on the optional value.

Note that it is only possible to return Object assertions after calling this method due to java generics limitations.

Example:

TolkienCharacter frodo = new TolkienCharacter("Frodo", 33, HOBBIT);

// Use get() to navigate to perform assertions on frodo.
assertThat(Optional.of(frodo)).get().isEqualTo(frodo);

// fails since the API does not allow navigating to a null value.
assertThat(Optional.empty()).get();

A variant of assertThatThrownBy which accepts a description has been added.

Example:

// this assertion fails ... 
assertThatThrownBy(() -> { throw new IOException("bam!"); }, "check explosion")
          .isInstanceOf(IOException.class)
          .hasMessageContaining("boom!");
// ... with the following error message:

java.lang.AssertionError: [check explosion] 
Expecting message:
 <"bam !">
but was:
 <"boom !">

Allow to set a description for assertions initialized with:

  • assertThatExceptionOfType
  • assertThatIllegalStateException
  • assertThatNullPointerException
  • assertThatIOException
  • assertThatIllegalArgumentException

Examples:

// assertions succeeds
assertThatExceptionOfType(RuntimeException.class)
                         .as("check explosion")
                         .isThrownBy(() -> {throw new RuntimeException("boom !");})
                         .withMessage("boom !");

assertThatNullPointerException()
                        .as("null check")
                        .isThrownBy(() -> {throw new NullPointerException("null !");})
                        .withMessage("null !");

// assertion fails ... 
assertThatExceptionOfType(RuntimeException.class)
                         .as("check explosion")
                         .isThrownBy(() -> {throw new RuntimeException("boom !");})
                         .withMessage("bam !");
// ... with the error below (note the description):
java.lang.AssertionError: [check explosion] 
  Expecting message:
  <"bam !">
  but was:
  <"boom !">

Release date : 2017-05-21

This release includes all changes from AssertJ core 2.8.0 and adds the following that are Java 8 specific.

  • New Instant assertions were missing the isBetween assertion which was available in Comparable assertions.
  • New Instant assertions were missing the isStriclyBetween assertion which was available in Comparable assertions.

Verifies that the actual Temporal is in the [start, end] period (start and end included).

Temporal types supported include: Instant, LocalDate, LocalDateTime, LocalTime, OffsetTime, OffsetDateTime and ZonedDateTime.

Examples with Instant :

Instant instant = Instant.now();

// assertions succeed
assertThat(instant).isBetween(instant.minusSeconds(1), instant.plusSeconds(1))
                   .isBetween(instant, instant.plusSeconds(1))
                   .isBetween(instant.minusSeconds(1), instant)
                   .isBetween(instant, instant);

Verifies that the actual Temporal is in the ]start, end[ period (start and end excluded).

Temporal types supported include Instant, LocalDate, LocalDateTime, LocalTime, OffsetTime, OffsetDateTime and ZonedDateTime.

Examples with Instant :

Instant instant = Instant.now();

// assertion succeeds
assertThat(instant).isStrictlyBetween(instant.minusSeconds(1), instant.plusSeconds(1));

// assertions fail
assertThat(instant).isStrictlyBetween(instant.plusSeconds(1), instant.plusSeconds(10));
assertThat(instant).isStrictlyBetween(instant, instant.plusSeconds(1));
assertThat(instant).isStrictlyBetween(instant.minusSeconds(1), instant);

Release date : 2017-05-07

This release includes all changes from AssertJ core 2.7.0 and adds the following that are Java 8 specific.

Thanks to Pascal Schumacher, Eirik Lygre, epeee, Kseniya Panasyuk, Gaël Lhez, Brice Dutheil, Takuya "Mura-Mi" Murakami and Maurício Aniche for their contributions.

  • AssertJ is compatible with Java 9. (Pascal Schumacher)
  • extracting and flatExtracting now accept extractor functions throwing checked exceptions. (epeee)
  • allMatch assertion now prints all non matching elements if it fails. (Maurício Aniche)
  • Add @CheckReturnValue for findbugs integration in WithAssertions. (Pascal Schumacher)
  • Improve error message of containsInstanceOf Optional assertion. (Eirik Lygre)
  • Code refactoring and cleanup. (Pascal Schumacher, epeee)
  • A bunch of javadoc improvements. (Pascal Schumacher, epeee)

Expose assertions for the Instant type from the new Date / Time API introduced in Java 8.

Examples:

import static org.assertj.core.api.Assertions.within;
import static org.assertj.core.api.Assertions.byLessThan;

Instant firstOfJanuary2000 = Instant.parse("2000-01-01T00:00:00.00Z");

// if you pass a String, AssertJ parses it to an Instant
assertThat(firstOfJanuary2000).isEqualTo("2000-01-01T00:00:00.00Z")
                              .isAfter("1999-12-31T23:59:59.99Z")
                              .isAfter(firstOfJanuary2000.minusSeconds(1))
                              .isAfterOrEqualTo("2000-01-01T00:00:00.00Z")
                              .isBefore(firstOfJanuary2000.plusSeconds(1))
                              .isBefore("2000-01-01T00:00:00.01Z")
                              .isCloseTo("1999-12-31T23:59:59.99Z", within(10, ChronoUnit.MILLIS))
                              .isCloseTo("1999-12-31T23:59:59.99Z", byLessThan(11, ChronoUnit.MILLIS));

Verifies that the actual Temporal is close to the other according to the given TemporalOffset.

You can build the offset parameter using:

  • Assertions.within(long, TemporalUnit)
  • Assertions.byLessThan(long, TemporalUnit)

Examples:

import static org.assertj.core.api.Assertions.within;
import static org.assertj.core.api.Assertions.byLessThan;

LocalTime _07_10 = LocalTime.of(7, 10);
LocalTime _07_42 = LocalTime.of(7, 42);

// assertions will pass
assertThat(_07_10).isCloseTo(_07_42, within(1, ChronoUnit.HOURS));
assertThat(_07_10).isCloseTo(_07_42, within(32, ChronoUnit.MINUTES));

// assertions will fail (byLessThan does not allow equals)
assertThat(_07_10).isCloseTo(_07_42, byLessThan(32, ChronoUnit.MINUTES));
assertThat(_07_10).isCloseTo(_07_42, within(10, ChronoUnit.SECONDS));

Verifies that at least one element satisfies the given requirements expressed as a Consumer.

If the iterable/array to assert is empty, the assertion will fail.

Example:

// assume that one of myIcelanderFriends has a name ending with 'son' (highly probable indeed)
assertThat(myIcelanderFriends).anySatisfy(person -> {
                                 assertThat(person.getCountry()).isEqualTo("Iceland");
                                 assertThat(person.getName()).endsWith("son");
                               });

Extend Stream assertions to primitive streams: IntStream , LongStream and DoubleStream.

Examples:

// IntStream example:
assertThat(IntStream.of(1, 2, 3)).contains(3)
                                 .anySatisfy(i -> assertThat(i).isLessThan(2));

// LongStream example:
assertThat(LongStream.of(0, 1, 2, 3, 4)).hasSize(5)
                                        .containsSequence(1L, 2L, 3L);

// DoubleStream example:
assertThat(DoubleStream.of(1, 2, 3)).hasSize(3)
                                    .contains(1.0, 2.0, 3.0)
                                    .allMatch(Double::isFinite);

Verify that a code block does not raise an exception. This allows finer control over statement(s) that should or should not raise an exception.

Example:

assertThatCode(() -> {}).doesNotThrowAnyException();

Provide the following assertThatExceptionOfType shortchuts:

  • assertThatNullPointerException
  • assertThatIllegalArgumentException
  • assertThatIllegalStateException
  • assertThatIOException

Example:

// instead of ...
assertThatExceptionOfType(IOException.class).isThrownBy(() -> { throw new IOException("boom!"); })
                                            .withMessage("boom!")
                                            .withMessageContaining("oom")
                                            .withMessage("%s!", "boom")
                                            .withStackTraceContaining("IOException")
                                            .withNoCause();
// ... you can simply write:
assertThatIOException().isThrownBy(() -> { throw new IOException("boom!"); })
                       .withMessage("boom!")
                       ... 

Verify that the object under test returns the given expected value from the given method expressed as a Function. A typical usage is to pass a method reference to assert an object's property.

Wrapping the given Function with Assertions.from makes the assertion more readable.

Examples:

import static org.assertj.core.api.Assertions.from;

// from is not mandatory but it makes the assertions more readable
assertThat(frodo).returns("Frodo", from(TolkienCharacter::getName))
                 .returns("Frodo", TolkienCharacter::getName) // no from :(
                 .returns(HOBBIT, from(TolkienCharacter::getRace));

Extracting and flatExtracting can be passed extractor functions that throw checked exceptions.

Any checked exception raised in the extractor is rethrown wrapped in a RuntimeException.

Examples:

// Instead of using an Extractor, we use a ThrowingExtractor
ThrowingExtractor<TolkienCharacter, Race, Exception> nonHobbitRace = tolkienCharacter -> {
  if (tolkienCharacter.getRace() == HOBBIT) {
    throw new Exception("Filthy little hobbites. They stole it from us. Myyy PRECIOUSSS !");
  }
  return tolkienCharacter.getRace();
};

// assertion succeeds
assertThat(newArrayList(elrond, aragorn)).extracting(nonHobbitRace)
                                         .containsOnly(ELF, MAN)
                                         .doesNotContain(HOBBIT);

// Error ! a RuntimeException wrapping the Exception raised from nonHobbitRace extractor is thrown
assertThat(fellowshipOfTheRing).extracting(nonHobbitRace)
                               .contains(HOBBIT, ELF)
                               .doesNotContain(ORC);

// flat extracting example
ThrowingExtractor<TolkienCharacter, Collection<String>, Exception> nameAndRaceExtractor =
  tolkienCharacter -> {
    if (tolkienCharacter == null) {
      throw new Exception("can't accept null TolkienCharacter");
    }
    return asList(tolkienCharacter.getName(), tolkienCharacter.getRace().getName());
};

assertThat(fellowshipOfTheRing).flatExtracting(nameAndRaceExtractor)
                               .contains("Hobbit", "Frodo", "Elf", "Legolas");

Release date : 2017-01-21

  • Fix extracting properties from default getter method.

Release date : 2016-11-27

  • Fix filteredOn(Predicate) that was only working with List.

Release date : 2016-11-21

This release includes all changes from AssertJ core 2.6.0 and adds the following that are Java 8 specific.

Thanks to Pascal Schumacher, Mike Kobit, Clément Mathieu, Kseniya Panasyuk, Gaël Lhez, Valeriy Vyrva and Filip Hrisafov for their contributions.

  • Parameterize registerFormatterForType with type. (Kseniya Panasyuk)
  • Predicate assertions error message improvements. (Filip Hrisafov)
  • Allow to pass a Predicate description to allMatch iterable/array assertion. (Filip Hrisafov)
  • Varargs warning removal. (Gaël Lhez)
  • Add missing assertThat in WithAssertions. (Clément Mathieu)
  • A bunch of code cleanup and javadoc improvements. (Pascal Schumacher, Mike Kobit)
  • Fix stack overflow for completable future toStringOf joining on another future that cycles back to the first. (Kseniya Panasyuk)

Verifies that the actual value is an instance of the given type satisfying the given requirements expressed as a Consumer.

This is typically used when one knows the real type of the object under test and wants to perform strongly typed assertions without having to do an explicit cast.

Example :

// Build Jedi but declare them as Object (second parameter is the light saber color)
Object yoda = new Jedi("Yoda", "Green");
Object luke = new Jedi("Luke Skywalker", "Green");

Consumer<Jedi> jediRequirements = jedi -> {
   assertThat(jedi.getLightSaberColor()).isEqualTo("Green");
   assertThat(jedi.getName()).doesNotContain("Dark");
};

// assertions succeed:
assertThat(yoda).isInstanceOfSatisfying(Jedi.class, jediRequirements);
assertThat(luke).isInstanceOfSatisfying(Jedi.class, jediRequirements);

Verifies that all elements satisfy the given requirements expressed as a Consumer. This is typically used to perform a group of assertions on every element of the iterable/array under test.

Example :

assertThat(myIcelanderFriends).allSatisfy(person -> {
                                 assertThat(person.getCountry()).isEqualTo("Iceland");
                                 assertThat(person.getPhoneCountryCode()).isEqualTo("+354");
                              });

Call map/flatMap on the Optional under test, assertions chained afterwards are performed on the Optional resulting from the map/flatMap call.

Example :

// map example
assertThat(Optional.of("42")).contains("42")
                             .map(String::length)
                             .contains(2);

// flatMap examples
Function<String, Optional<String>> UPPER_CASE_OPTIONAL_STRING
          = s -> s == null ? Optional.empty() : Optional.of(s.toUpperCase());

assertThat(Optional.of("something")).contains("something")
                                    .flatMap(UPPER_CASE_OPTIONAL_STRING)
                                    .contains("SOMETHING");

assertThat(Optional.<String> empty()).flatMap(UPPER_CASE_OPTIONAL_STRING)
                                     .isEmpty();

assertThat(Optional.<String> ofNullable(null)).flatMap(UPPER_CASE_OPTIONAL_STRING)
                                              .isEmpty();

Verifies that the actual Map contains the given key and that its value satisfies the given requirements expressed as a Consumer.

Example:

Map<Ring, TolkienCharacter> ringBearers = new HashMap<>();
ringBearers.put(nenya, galadriel);
ringBearers.put(narya, gandalf);
ringBearers.put(vilya, elrond);
ringBearers.put(oneRing, frodo);

// this assertion will pass
assertThat(ringBearers).hasEntrySatisfying(nenya, character -> {
   assertThat(character.getName()).contains("driel");
   assertThat(character.getRace()).isEqualTo(ELF);
});

// this assertion will fail
assertThat(ringBearers).hasEntrySatisfying(oneRing, character -> {
   assertThat(character.getRace()).isEqualTo(ELF);
});

Verifies that the actual Optional contains a value which satisfies the given Condition.

Example:

Condition<TolkienCharacter> isAnElf = new Condition<>(character -> character.getRace() == ELF, "an elf");

TolkienCharacter legolas = new TolkienCharacter("Legolas", 1000, ELF);
TolkienCharacter frodo = new TolkienCharacter("Frodo", 33, HOBBIT);

// assertion succeeds
assertThat(Optional.of(legolas)).hasValueSatisfying(isAnElf);

This is an alternative to JUnitSoftAssertions and AutoCloseableSoftAssertions to avoid having to call assertAll manually.

Example:

@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");
      // no need to call assertAll, it is done by assertSoftly.
   });
}

Improves the allMatch iterable/array assertion error message by passing a description of the given predicate.

Assertion error message example:

List<TolkienCharacter> hobbits = newArrayList(frodo, sam, pippin, sauron);

// assertion fails (as expected) ...
assertThat(hobbits).allMatch(character -> character.getRace() == HOBBIT, "hobbits");
//... giving this error message:
java.lang.AssertionError:
Expecting all elements of:
  <[Frodo 33 years old Hobbit,
    Sam 38 years old Hobbit,
    Pippin 28 years old Hobbit,
    Sauron 50000 years old Maia]>
to match 'hobbits' predicate but this element did not:
  <Sauron 50000 years old Maia>

Release date : 2016-07-17

Thanks to Cristiano Gavião for the fix.

  • Fix MANIFEST.MF that was importing ant packages. (Cristiano Gavião)

Release date : 2016-07-03

This release includes all changes from AssertJ core 2.5.0 and adds some specific to Java 8.

The 3.5.1 release fixes a regression of the Stream isEqualTo assertion which was changed in 3.5.0 to support reference comparison.

Thanks to Pascal Schumacher, Dima Gerasimov, tommyshem, Filip Hrisafov, Fabien Duminy and timmikk for their contributions.

  • Better cross OS line separator support in error messages. (timmikk)
  • Soft assertions output line numbers of failed assertions. (Pascal Schumacher, Fabien Duminy)
  • Javadoc improvements. (Pascal Schumacher, tommyshem)
  • Fix Stream assertions relying on checking the original stream (ex: isSameAs).

The following Predicate assertions are available:

  • accepts(T... values) : succeeds if all given values match the Predicate under test
  • rejects(T... values) : succeeds if no given value matches the Predicate under test
  • acceptsAll(Iterable) : succeeds if all elements of the given Iterable match the Predicate under test
  • rejectsAll(Iterable) : succeeds if no elements of the given Iterable match the Predicate under test

Example : accepts & acceptsAll

Predicate<String> ballSportPredicate = sport -> sport.contains("ball");

// assertion succeeds:
assertThat(ballSportPredicate).accepts("football")
                              .accepts("football", "basketball", "handball");
assertThat(ballSportPredicate).acceptsAll(list("football", "basketball", "handball"));

// assertion fails because of curling :p
assertThat(ballSportPredicate).accepts("curling")
assertThat(ballSportPredicate).accepts("football", "basketball", "curling");
assertThat(ballSportPredicate).acceptsAll(list("football", "basketball", "curling"));

Example : rejects & rejectsAll

Predicate<String> ballSportPredicate = sport -> sport.contains("ball");

// assertion succeeds:
assertThat(ballSportPredicate).rejects("curling")
                              .rejects("curling", "judo", "marathon");
assertThat(ballSportPredicate).rejectsAll(list("curling", "judo", "marathon"));

// assertion fails because of football:
assertThat(ballSportPredicate).rejects("football");
assertThat(ballSportPredicate).rejects("curling", "judo", "football");
assertThat(ballSportPredicate).rejectsAll(list("curling", "judo", "football"));

Verifies that the actual object satisfied the given requirements expressed as a Consumer<T>.

This is useful to perform a group of assertions on multiple objects or to avoid having to declare a local variable in order to use multiple assertions on a single object.

Example :

// second constructor parameter is the light saber color
Jedi yoda = new Jedi("Yoda", "Green");
Jedi luke = new Jedi("Luke Skywalker", "Green");

Consumer<Jedi> jediRequirements = jedi -> {
   assertThat(jedi.getLightSaberColor()).isEqualTo("Green");
   assertThat(jedi.getName()).doesNotContain("Dark");
};

// assertions succeed:
assertThat(yoda).satisfies(jediRequirements);
assertThat(luke).satisfies(jediRequirements);

// assertions fails:
Jedi vader = new Jedi("Vader", "Red");
assertThat(vader).satisfies(jediRequirements);

In the following example, satisfies allows multiple assertions without the declaration of a local variable:

// no need to define team.getPlayers().get(0).getStats() as a local variable
assertThat(team.getPlayers().get(0).getStats()).satisfies(stats -> {
   assertThat(stats.pointPerGame).isGreaterThan(25.7);
   assertThat(stats.assistsPerGame).isGreaterThan(7.2);
   assertThat(stats.reboundsPerGame).isBetween(9, 12);
};

Assertions error messages use a Representation to format the different types involved. By using registerFormatterForType you can control the formatting of a given type by providing a specific formatter.

Registering a formatter makes it available to all of AssertJs representations:
  • StandardRepresentation
  • UnicodeRepresentation
  • HexadecimalRepresentation
  • BinaryRepresentation

Example :

// without specific formatter
assertThat(STANDARD_REPRESENTATION.toStringOf(123L)).isEqualTo("123L");

// register a formatter for Long
Assertions.registerFormatterForType(Long.class, value -> "$" + value + "$");

// now Longs will be formatted between $ in error messages
assertThat(STANDARD_REPRESENTATION.toStringOf(longNumber)).isEqualTo("$123$");

// The following assertion fails ...
assertThat(123L).isEqualTo(456L);
// ... with error :
expected:<$456$> but was:<$123$>

Verifies that the iterable/array contains only a single element and that the element satisfies the given assertions expressed as a Consumer. If it does not, only the first error is reported (use SoftAssertions to get all errors).

Example :

List<Jedi> jedis = asList(new Jedi("Yoda", "red"));

// assertions will pass
assertThat(jedis).hasOnlyOneElementSatisfying(yoda -> assertThat(yoda.getName()).startsWith("Y"));

assertThat(jedis).hasOnlyOneElementSatisfying(yoda -> {
 assertThat(yoda.getName()).isEqualTo("Yoda");
 assertThat(yoda.getLightSaberColor()).isEqualTo("red");
});

// assertion will fail
assertThat(jedis).hasOnlyOneElementSatisfying(yoda -> assertThat(yoda.getName()).startsWith("Vad"));

// fails as one the assertions is not satisfied
assertThat(jedis).hasOnlyOneElementSatisfying(yoda -> {
 assertThat(yoda.getName()).isEqualTo("Yoda");
 assertThat(yoda.getLightSaberColor()).isEqualTo("purple");
});

// fails but only reports the first error
assertThat(jedis).hasOnlyOneElementSatisfying(yoda -> {
 assertThat(yoda.getName()).isEqualTo("Luke");
 assertThat(yoda.getLightSaberColor()).isEqualTo("green");
});

// fails and reports all errors thanks to SoftAssertions
assertThat(jedis).hasOnlyOneElementSatisfying(yoda -> {
 SoftAssertions softly = new SoftAssertions();
 softly.assertThat(yoda.getName()).isEqualTo("Luke");
 softly.assertThat(yoda.getLightSaberColor()).isEqualTo("green");
 softly.assertAll();
});

jedis.add(new Jedi("Luke", "green"));

// fails : the given assertion requirements are met but there are too many jedis !
assertThat(jedis).hasOnlyOneElementSatisfying(yoda -> assertThat(yoda.getName()).startsWith("Yo"));

Extracts multiple values from each Iterable's element according to the given Extractors and concatenates/flattens the extracted values into a list that is used as the new object under test.

If the extracted values were not flattened, instead of a simple list like (given 2 extractors) :

  element1.value1, element1.value2, element2.value1, element2.value2, ...

we would get a list of list like :

  list(element1.value1, element1.value2), list(element2.value1, element2.value2), ...

Example :

// fellowshipOfTheRing is a List<TolkienCharacter>

// values are extracted in order and flattened : age1, name1, age2, name2, age3 ...
assertThat(fellowshipOfTheRing).flatExtracting(TolkienCharacter::getAge,
                                               TolkienCharacter::getName)
                               .contains(33 ,"Frodo",
                                         1000, "Legolas",
                                         87, "Aragorn");