Release date : 2018-05-12
This is a bugfix release as 2.x is not actively developped.
Thanks to Andrey Kuzmin for his contributions.
Release date : 2018-01-02
This is the last release with new features for Java 7, the next 2.x releases will be bugfixes releases.
Thanks to Pascal Schumacher, Marko Bekhta, epeee, Kseniya Panasyuk, Filip Hrisafov, Marco Leichsenring, João Delgado, Florent Biville, BillyYccc, Rudi Klassen, Daniel Weber, Chris Arnott, Bojan Trajkovski, and cal101 for their contributions.
Use assumeThat methods to express preconditions for test execution. All AssertJ assertions can be reused to express assumptions. Assumptions support both JUnit and TestNG.
All tests with unmet assumptions are skipped (provided you express assumptions before the test content).
Example with met assumptions:
import static org.assertj.core.api.Assumptions.assumeThat;
// since this assumption is true ...
assumeThat(frodo.getRace()).isEqualTo(HOBBIT);
// ... this assertion is performed.
assertThat(fellowshipOfTheRing).doesNotContain(sauron);
Example with unmet assumptions:
import static org.assertj.core.api.Assumptions.assumeThat;
// since this assumption is obviously false ...
assumeThat(frodo.getRace()).isEqualTo(ORC);
// ... this assertion is not performed and the test is skipped.
assertThat(fellowshipOfTheRing).contains(sauron);
Verifies that all elements in the actual Iterable
do not have the specified types (including subclasses).
Example:
List<Number> numbers = new ArrayList<>();
numbers.add(1);
numbers.add(2);
numbers.add(3.0);
// successful assertion:
assertThat(numbers).doesNotHaveAnyElementsOfTypes(Long.class, Float.class);
// assertion failure:
assertThat(numbers).doesNotHaveAnyElementsOfTypes(Long.class, Integer.class);
Verifies that the actual iterable/array contains exactly the given iterable elements and nothing else, in any order.
Example:
// an Iterable is used in the example but this also works with arrays
Iterable elvesRings = list(vilya, nenya, narya, vilya);
Iterable elvesRingsDifferentOrder = list(nenya, narya, vilya, vilya);
// assertion succeeds
assertThat(elvesRings).containsExactlyInAnyOrder(elvesRingsDifferentOrder);
// assertion fails as vilya is contained twice in elvesRings
assertThat(elvesRings).containsExactlyInAnyOrder(list(vilya, nenya, narya));
Verifies that the actual group contains only null elements and nothing else.
Example:
// assertion succeeds
Iterable<String> items = Arrays.asList(null, null, null);
assertThat(items).containsOnlyNulls();
// assertion fails because items2 contains a not null element
Iterable<String> items2 = Arrays.asList(null, null, "notNull");
assertThat(items2).containsOnlyNulls();
// assertion fails since an empty iterable does not contain anything and therefore not null
Iterable<String> empty = new ArrayList<>();
assertThat(empty).containsOnlyNulls();
Verifies that the actual iterable/array contains at least one of the given values.
Example:
Iterable<String> abc = Arrays.asList("a", "b", "c");
// assertions succeeds
assertThat(abc).containsAnyOf("b")
.containsAnyOf("b", "c")
.containsAnyOf("a", "b", "c")
.containsAnyOf("a", "b", "c", "d")
.containsAnyOf("e", "f", "g", "b");
// assertions fail
assertThat(abc).containsAnyOf("d");
assertThat(abc).containsAnyOf("d", "e", "f", "g");
Allows to reuse Hamcrest matchers as Conditions.
Example:
import static org.hamcrest.core.StringContains.containsString;
Condition<String> aStringContaining123 = new HamcrestCondition<>(containsString("123"));
// assertions succeed
assertThat("abc123").is(aStringContaining123);
assertThat("def456").isNot(aStringContaining123);
Allow to register a representation as a service discovered at program startup. The advantage of registering a representation is that you don't need to do anything in your tests, the java runtime will discover it and AssertJ will use it but it requires a bit more work than a simple call to Assertions.useRepresentation(Representation).
To register a Representation, you need to do several things:
We recommend that you extend StandardRepresentation and override fallbackToStringOf(Object). By doing this all the defaults of AssertJ would be applied and you can apply your own customization.
Placing META-INF/services/org.assertj.core.presentation.Representation in src/test/resources should be enough to put it in the classpath.
The assertj-examples project provides a working example, see:Verifies that the actual object has the same hashCode as the given object.
Example:
// assertions will pass
assertThat(42L).hasSameHashCodeAs(42L);
assertThat("The Force").hasSameHashCodeAs("The Force");
assertThat(new Jedi("Yoda", "Blue")).hasSameHashCodeAs(new Jedi("Yoda", "Blue"));
// assertions will fail
assertThat(42L).hasSameHashCodeAs(2501L);
assertThat(null).hasSameHashCodeAs("The Force");
assertThat("The Force").hasSameHashCodeAs(null);
Allows to set a specific comparator for the given type of elements or their fields. It extends usingComparatorForElementFieldsWithType by applying the provided comparator to elements themselves, not only to their fields.
Usage of this method affects comparators set by next methods:
Example:
// assertion will pass as BigDecimal comnparator 1.0 is equalto to 1.00
assertThat(asList("some", new BigDecimal("4.2")))
.usingComparatorForType(BIG_DECIMAL_COMPARATOR, BigDecimal.class)
.contains(new BigDecimal("4.20"));
Verifies that the actual String is equal to the given one after both strings new lines (\n, \r\n) have been removed.
Example:
// assertions succeed
assertThat("Some text\nWith new lines").isEqualToIgnoringNewLines("Some textWith new lines")
.isEqualToIgnoringNewLines("Some text\nWith new lines")
.isEqualToIgnoringNewLines("Some text\r\nWith new lines")
.isEqualToIgnoringNewLines("Some text\n\nWith new lines");
// assertion fails
assertThat("Some text\nWith new lines").isEqualToIgnoringNewLines("Some text With new lines");
Flatten the values of the given keys from the actual map under test into a new array, this new array becoming the object under test. The order of values in the resulting array is the order of the map keys iteration then key values.
If a given key is not present in the map under test, a null value is extracted.
If a given key value is not an Iterable or an array, it is simply extracted but (obviously) not flattened.
If a given key value is an Iterable or an array, it is flattened.
Example:
List<String> names = asList("Dave", "Jeff");
LinkedHashSet<String> jobs = newLinkedHashSet("Plumber", "Builder");
Iterable<String> cities = asList("Dover", "Boston", "Paris");
int[] ranks = { 1, 2, 3 };
Map<String, Object> map = new LinkedHashMap<>();
map.put("name", names);
map.put("job", jobs);
map.put("city", cities);
map.put("rank", ranks);
assertThat(map).flatExtracting("name", "job", "city", "rank")
.containsExactly("Dave", "Jeff",
"Plumber", "Builder",
"Dover", "Boston", "Paris",
1, 2, 3);
// the order of values in the resulting array is the order of map keys then key values:
assertThat(map).flatExtracting("city", "job", "name")
.containsExactly("Dover", "Boston", "Paris",
"Plumber", "Builder",
"Dave", "Jeff");
// contains exactly null twice (one for each unknown keys)
assertThat(map).flatExtracting("foo", "name", "bar")
.containsExactly(null, "Dave", "Jeff", null);
// if the key value is not an iterable/array, it will be simply extracted but not flattened:
map.put("year", 2017);
assertThat(map).flatExtracting("name", "job", "year")
.containsExactly("Dave", "Jeff", "Plumber", "Builder", 2017);
Verifies that the actual String contains the given sequence of values in the given order and since 2.9.0/3.9.0 without any other values between them.
This behavior is consistent with iterable/array containsSequence assertion.
If you need the old behavior, simply use the containsSubsequence assertion instead.
Example:
String book = "{ 'title':'A Game of Thrones', 'author':'George Martin'}";
// this assertions succeed, you can use a varargs or an iterable to provide the sequence
assertThat(book).containsSequence("'title'", ":", "'A Game of Thrones'");
assertThat(book).containsSequence(Arrays.asList("'title'", ":", "'A Game of Thrones'"));
// this assertion will fail because there are values between the expected sequence (e.g "'title':'")
// this used to pass before 2.9.0/3.9.0
assertThat(book).containsSequence("{", "A Game of Thrones", "George Martin", "}");
// this one fails as ":" must come after "'title'"
assertThat(book).containsSequence(":", "'title'", "'A Game of Thrones'");
Verifies that the actual String contains the given values in the given order, possibly with other values between them.
Example:
String book = "{ 'title':'A Game of Thrones', 'author':'George Martin'}";
// this assertions succeed, you can use a varargs or an iterable to provide the subsequence
assertThat(book).containsSubsequence("'title'", ":", "'A Game of Thrones'");
assertThat(book).containsSubsequence(Arrays.asList("'title'", ":", "'A Game of Thrones'");
// this one too even if there are values between the expected sequence (e.g "'title':'")
assertThat(book).containsSubsequence("{", "A Game of Thrones", "George Martin", "}");
// this one fails as "author" must come after "A Game of Thrones"
assertThat(book).containsSubsequence("{", "author", "A Game of Thrones", "}");
Verifies that the actual String is blank, i.e. is null, empty or consists of one or more whitespace characters (according to Character.isWhitespace(char)).
The definition of "blank" has changed, the old behaviour is now under containsOnlyWhitespaces.
Example:
// these assertions succeed:
assertThat(" ").isBlank();
assertThat("").isBlank();
assertThat(" ").isBlank();
String nullString = null;
assertThat(nullString).isBlank();
// these assertions fail:
assertThat("a").isBlank();
assertThat(" b").isBlank();
assertThat(" c ").isBlank();
Verifies that the actual String consists of one or more whitespace characters (according to Character.isWhitespace(char)).
Example:
// these assertions succeed:
assertThat(" ").containsOnlyWhitespaces();
assertThat(" ").containsOnlyWhitespaces();
// these assertions fail:
assertThat("a").containsOnlyWhitespaces();
assertThat("").containsOnlyWhitespaces();
assertThat(" b").containsOnlyWhitespaces();
assertThat(" c ").containsOnlyWhitespaces();
String nullString = null;
assertThat(nullString).containsOnlyWhitespaces();
Verifies that the actual number is close to the given one within the given offset value.
When abs(actual - expected) == offset value, the assertion:
Breaking change since 2.9.0/3.9.0: using Assertions.byLessThan(Integer) implies a strict comparison, use Assertions.within(Integer) to get the old behavior.
Example:
// assertions succeed:
assertThat(5).isCloseTo(7, within(3));
assertThat(5).isCloseTo(7, byLessThan(3));
// if difference is exactly equals to the offset, it's ok ...
assertThat(5).isCloseTo(7, within(2));
// ... but not with byLessThan which implies a strict comparison
assertThat(5).isCloseTo(7, byLessThan(2)); // FAIL
// assertions fail
assertThat(5).isCloseTo(7, within(1));
assertThat(5).isCloseTo(7, byLessThan(1));
assertThat(5).isCloseTo(7, byLessThan(2));
Release date : 2017-05-21
Thanks to Pascal Schumacher for his contributions.
Verifies that the actual String is equal to the given one, ignoring whitespace differences.
In the old behavior Strings were compared after normalizing their whitespaces but not truly ignoring them (see isEqualToNormalizingWhitespace).
Examples:
// assertions succeed
assertThat("Game of Thrones").isEqualToIgnoringWhitespace("Game of Thrones")
.isEqualToIgnoringWhitespace(" Game of Thrones ")
.isEqualToIgnoringWhitespace(" Game of Thrones ")
.isEqualToIgnoringWhitespace("Gameof Thrones")
.isEqualToIgnoringWhitespace("Game of\tThrones")
.isEqualToIgnoringWhitespace("GameofThrones");
// this one succeeds but would have failed with the previous assertion behavior:
assertThat("Game of Thrones").isEqualToIgnoringWhitespace("GameofThrones");
This assertion behaves like the old isEqualToIgnoringWhitespace. It verifies that the actual String is equal to the given one, after the whitespace of both strings has been normalized.
To be precise, the following whitespace rules are applied:
Example :
// assertions will pass
assertThat("Game of Thrones").isEqualToNormalizingWhitespace("Game of Thrones")
.isEqualToNormalizingWhitespace("Game of Thrones")
.isEqualToNormalizingWhitespace("Game of Thrones")
.isEqualToNormalizingWhitespace(" Game of Thrones ")
.isEqualToNormalizingWhitespace(" Game of Thrones ")
.isEqualToNormalizingWhitespace("Game of\tThrones")
.isEqualToNormalizingWhitespace("Game of Thrones");
// assertions will fail, after normalization we have whitespace differences
assertThat("Game of Thrones").isEqualToNormalizingWhitespace("GameofThrones");
assertThat("Game of Thrones").isEqualToNormalizingWhitespace("Gameof Thrones");
assertThat("Game of Thrones").isEqualToNormalizingWhitespace("Gameo fThrones");
Release date : 2017-05-07
Thanks to Pascal Schumacher, epeee, Kseniya Panasyuk, Filip Hrisafov, Drummond Dawson, Dmitrii Nikitin, Julian Honnen, Maurício Aniche, Tomasz Kalkosiński, Joey Bratton, Martin Winandy, Christopher Arnott, Ruben Dijkstra, Michał Szkutnik and Antoine Dessaigne for their contributions.
I would like to specially thank (again) epeee and Kseniya Panasyuk for their many contributions, awesome guys !
Add assertions for Future (CompletableFuture assertions are already available in AssertJ Core 3.x).
Example :
ExecutorService executorService = Executors.newSingleThreadExecutor();
// this future is going to complete (almost) immediately
Future<String>> future = executorService.submit(new Callable<String>>() {
@Override
public String call() throws Exception {
return "done";
}
});
// just to be sure the Future is complete
Thread.sleep(100);
assertThat(future).isDone()
.isNotCancelled();
// create a future that is going to take one second to complete
future = executorService.submit(new Callable<String>>() {
@Override
public String call() throws Exception {
Thread.sleep(1000);
return "done";
}
});
// not done yet (it will after one second)
assertThat(future).isNotDone()
.isNotCancelled();
future.cancel(true);
assertThat(future).isCancelled();
Add assertions for the following atomic classes:
Atomic assertions are similar to their non atomic counterparts. For example the AtomicLong assertion has the same methods as the Long assertion.
Example :
import static org.assertj.core.api.Assertions.within;
import static org.assertj.core.api.Assertions.withinPercentage;
// AtomicInteger assertions (AtomicLong assertions are similar)
AtomicInteger atomicInteger = new AtomicInteger(42);
assertThat(atomicInteger).hasValue(42)
.doesNotHaveValue(50)
.hasPositiveValue()
.hasValueLessThan(50)
.hasValueGreaterThan(40)
.hasValueBetween(40, 50)
.hasValueCloseTo(45, within(3))
.hasValueCloseTo(45, withinPercentage(10));
// AtomicBoolean assertions
AtomicBoolean atomicBoolean = new AtomicBoolean(true);
assertThat(atomicBoolean).isTrue();
// AtomicLongArray assertions
AtomicLongArray atomicLongArray = new AtomicLongArray(new long[] { 1, 2, 3 });
assertThat(atomicLongArray).isNotEmpty()
.startsWith(1, 2)
.endsWith(3);
// AtomicReference assertions
AtomicReference<String> atomicReference = new AtomicReference<>("foo");
assertThat(atomicReference).hasValue("foo")
.doesNotHaveValue("bar");
// AtomicReferenceArray assertions
AtomicReferenceArray<String> abc = new AtomicReferenceArray<>(new String[] { "a", "b", "c" });
assertThat(abc).contains("b", "a")
.contains("b", "a", "b");
// AtomicIntegerFieldUpdater assertions for TolkienCharacter's age which is a volatile public int field
AtomicIntegerFieldUpdater<TolkienCharacter> ageUpdater = newUpdater(TolkienCharacter.class, "age");
ageUpdater.set(gandalf, 25);
assertThat(ageUpdater).hasValue(25, gandalf);
Extend existing number assertions to BigInteger.
Examples:
import static org.assertj.core.api.Assertions.within;
import static org.assertj.core.api.Assertions.withinPercentage;
BigInteger eleven = new BigInteger("11");
assertThat(BigInteger.TEN).isGreaterThan(BigInteger.ONE)
.isGreaterThanOrEqualTo(BigInteger.TEN)
.isLessThan(eleven)
.isLessThanOrEqualTo(BigInteger.TEN)
.isBetween(BigInteger.ONE, eleven)
.isCloseTo(eleven, within(BigInteger.ONE))
.isCloseTo(eleven, withinPercentage(20))
.isPositive()
.isNotNegative();
assertThat(BigInteger.ONE).isOne();
Add assertions to verify the existence and visibility of the fields and methods of a class.
Examples:
class MySuperClass {
public void superMethod() {}
private void privateSuperMethod() {}
}
class MyClass extends MySuperClass {
// fields
public String fieldOne;
public String fieldTwo;
private String fieldThree;
// methods
public void methodOne() {}
private void methodTwo() {}
}
// field assertions
assertThat(MyClass.class).hasPublicFields("fieldTwo", "fieldOne")
.hasDeclaredFields("fieldThree", "fieldTwo", "fieldOne")
.hasOnlyPublicFields("fieldOne", "fieldTwo")
.hasOnlyDeclaredFields("fieldThree", "fieldTwo", "fieldOne");
// method assertions
assertThat(MyClass.class).hasMethods("methodOne", "methodTwo", "superMethod", "privateSuperMethod")
.hasPublicMethods("methodOne", "superMethod")
.hasDeclaredMethods("methodTwo", "methodOne");
Verifies the visibility of a class.
Examples:
assertThat(String.class).isPublic();
protected class MyClass {
// ...
}
assertThat(MyClass.class).isProtected();
Verifies that two Strings are equal ignoring newline differences, that is considering '\r\n' to be equal to '\n'.
Examples:
String bookName = "Lord of the Rings\r\n";
assertThat(bookName).isEqualToNormalizingNewlines("Lord of the Rings\n");
// it does not ignore newlines though so this assertion fails:
assertThat("\n").isEqualToNormalizingNewlines("");
Use AssertJ assertions as a Hamcrest Matcher by extending AssertionMatcher.
Overriding classes should only implement the assertion(T) method as Matcher.matches(T) and SelfDescribing.describeTo(Description) are provided.
If the matcher fails, the description will contain the stacktrace of the first failed assertion.
Example with Mockito:
verify(customerRepository).save(argThat(new AssertionMatcher<Customer>() {
@Override
public void assertion(Customer actual) {
assertThat(actual).hasName("John")
.hasAge(30);
}
})
);
Verifies that the actual map contains an entry satisfying the given entry or key and value Condition.
Example:
Map<TolkienCharacter, Ring> ringBearers = new HashMap<>();
ringBearers.put(galadriel, nenya);
ringBearers.put(gandalf, narya);
ringBearers.put(elrond, vilya);
ringBearers.put(frodo, oneRing);
// entry Condition
Condition<Map.Entry<TolkienCharacter, Ring>> oneRingManBearer =
new Condition<Map.Entry<TolkienCharacter, Ring>>("One ring man bearer") {
public boolean matches(Map.Entry<TolkienCharacter, Ring> entry) {
return entry.getKey().getRace() == MAN && entry.getValue() == oneRing;
}
};
// key Condition
Condition<TolkienCharacter> isMan = new Condition<TolkienCharacter>("is man") {
public boolean matches(TolkienCharacter tolkienCharacter) {
return tolkienCharacter.getRace() == MAN;
}
};
// value Condition
Condition<Ring> oneRingBearer = new Condition<Ring>("One ring bearer") {
public boolean matches(Ring ring) {
return ring == oneRing;
}
};
// assertions fail
assertThat(ringBearers).hasEntrySatisfying(oneRingManBearer);
assertThat(ringBearers).hasEntrySatisfying(isMan, oneRingBearer);
ringBearers.put(isildur, oneRing);
// now assertions succeed since we have added isildur
assertThat(ringBearers).hasEntrySatisfying(oneRingManBearer);
assertThat(ringBearers).hasEntrySatisfying(isMan, oneRingBearer);
Verifies that the actual map contains an entry with a key satisfying the given Condition.
Example:
Map<TolkienCharacter, Ring> ringBearers = new HashMap<>();
ringBearers.put(galadriel, nenya);
ringBearers.put(gandalf, narya);
ringBearers.put(elrond, vilya);
ringBearers.put(frodo, oneRing);
Condition<TolkienCharacter> isElf = new Condition<TolkienCharacter>("is elf") {
public boolean matches(TolkienCharacter tolkienCharacter) {
return tolkienCharacter.getRace() == ELF;
}
};
Condition<TolkienCharacter> isOrc = new Condition<TolkienCharacter>("is orc") {
public boolean matches(TolkienCharacter tolkienCharacter) {
return tolkienCharacter.getRace() == ORC;
}
};
// assertion will pass
assertThat(ringBearers).hasKeySatisfying(isElf);
// assertion will fail
assertThat(ringBearers).hasKeySatisfying(isOrc);
Verifies that the actual map contains an entry with a value satisfying the given Condition.
Example:
Map<Ring, TolkienCharacter> ringBearers = new HashMap<>();
ringBearers.put(nenya, galadriel);
ringBearers.put(narya, gandalf);
ringBearers.put(vilya, elrond);
ringBearers.put(oneRing, frodo);
Condition<TolkienCharacter> isElf = new Condition<TolkienCharacter>("is elf") {
public boolean matches(TolkienCharacter tolkienCharacter) {
return tolkienCharacter.getRace() == ELF;
}
};
Condition<TolkienCharacter> isOrc = new Condition<TolkienCharacter>("is orc") {
public boolean matches(TolkienCharacter tolkienCharacter) {
return tolkienCharacter.getRace() == ORC;
}
};
// assertion will pass
assertThat(ringBearers).hasValueSatisfying(isElf);
// assertion will fail
assertThat(ringBearers).hasValueSatisfying(isOrc);
Verifies that all elements of the actual iterable/array are instances of the given types.
Example:
Iterable<? extends Object> objects = Arrays.asList("foo", new StringBuilder());
// assertions will pass
assertThat(objects).hasOnlyElementsOfTypes(CharSequence.class);
assertThat(objects).hasOnlyElementsOfTypes(String.class, StringBuilder.class);
// assertions will fail
assertThat(objects).hasOnlyElementsOfTypes(Number.class);
assertThat(objects).hasOnlyElementsOfTypes(String.class, Number.class);
assertThat(objects).hasOnlyElementsOfTypes(String.class);
Verifies that the actual iterable/array does not contain the given sequence. A sequence is defined as an ordered group of values without extra values between them.
Example:
Iterable<Ring> elvesRings = newArrayList(vilya, nenya, narya);
// assertions will pass, the elements order is correct but there is a value between them (nenya)
assertThat(elvesRings).doesNotContainSequence(vilya, narya)
.doesNotContainSequence(nenya, vilya);
// assertions will fail since proper sequence are passed
assertThat(elvesRings).doesNotContainSequence(vilya, nenya);
assertThat(elvesRings).doesNotContainSequence(nenya, narya);
Verifies that the actual group does not contain the given subsequence. A subsequence is defined as an ordered group of values with possibly extra values between them.
Example:
Iterable<Ring> elvesRings = newArrayList(vilya, nenya, narya);
// assertions will pass
assertThat(elvesRings).doesNotContainSubsequence(nenya, vilya)
.doesNotContainSubsequence(narya, vilya);
// assertion will fail
assertThat(elvesRings).doesNotContainSubsequence(vilya, nenya);
assertThat(elvesRings).doesNotContainSubsequence(vilya, narya);
Verifies that the actual String does not contain the given regular expression expressed either as a Pattern or a String.
Examples:
// assertions will pass
assertThat("Frodo").doesNotContainPattern(Pattern.compile("Fr.ud"));
assertThat("Frodo").doesNotContainPattern("Fr.ud");
// assertions will fail
assertThat("Freud").doesNotContainPattern(Pattern.compile("Fr.ud"));
assertThat("Freud").doesNotContainPattern("Fr.ud");
Release date : 2016-11-21
Many thanks to Class Augner, Pascal Schumacher, Mike Wilkes, Kseniya Panasyuk, Valeriy Vyrva, Chris Arnott, Gaël Lhez and Filip Hrisafov for their contributions.
fail methods have been added to soft assertions filling the gap with standard assertions.
Example :
SoftAssertions soft = new SoftAssertions();
soft.assertThat("foo").startsWith("boo");
assertThat(soft.errorsCollected()).hasSize(1);
soft.fail("Fail");
assertThat(soft.errorsCollected()).hasSize(2);
The new fail method allows to build the error message like String.format.
Example :
try {
fail("I prefer %s over %s", "Batman", "Superman");
} catch (AssertionError e) {
assertThat(e).hasMessage("I prefer Batman over Superman");
}
Add int based version of assertions that were taking byte parameters.
One example (amongst many new assertions) :
// before
assertThat(new byte[] { 1, 2, 3 }).contains((byte)1, (byte)2);
// after
assertThat(new byte[] { 1, 2, 3 }).contains(1, 2);
containsExactlyInAnyOrder was initially added for iterable/object arrays, it is now available for primitive arrays. It verifies that the actual array contains exactly the given values and nothing else, in any order.
Example with int array :
// this containsExactlyInAnyOrder assertion succeeds
assertThat(new int[] { 1, 2, 1 }).containsExactlyInAnyOrder(1, 1, 2);
// whereas containsExactly fails given the same input as the order of values is different:
assertThat(new int[] { 1, 2, 1 }).containsExactly(1, 1, 2);
Verifies that the actual Throwable has a suppressed exception similar to the given one, that is with the same type and message (no use of the equals method).
Example:
Throwable throwable = new Throwable();
Throwable invalidArgException = new IllegalArgumentException("invalid argument");
throwable.addSuppressed(invalidArgException);
// These assertions succeed:
assertThat(throwable).hasSuppressedException(invalidArgException);
assertThat(throwable).hasSuppressedException(new IllegalArgumentException("invalid argument"));
// These assertions fail:
assertThat(throwable).hasSuppressedException(new IllegalArgumentException("invalid parameter"));
assertThat(throwable).hasSuppressedException(new NullPointerException());
Verifies that the actual Throwable has no suppressed exceptions.
Example:
Throwable throwable = new Throwable();
// this assertion succeeds
assertThat(new Throwable()).hasNoSuppressedExceptions();
// this one fails
throwable.addSuppressed(new IllegalArgumentException());
assertThat(throwable).hasNoSuppressedExceptions();
Verifies that the actual map contains a value for the given key that satisfies the given Condition.
Example:
Map<Ring, TolkienCharacter> ringBearers = new HashMap<>();
ringBearers.put(nenya, galadriel);
ringBearers.put(narya, gandalf);
ringBearers.put(vilya, elrond);
ringBearers.put(oneRing, frodo);
Condition<TolkienCharacter> elfBearer = new Condition<>(tc -> tc.getRace() == ELF, "an elf bearer");
// this assertion will pass
assertThat(ringBearers).hasEntrySatisfying(nenya, elfBearer);
// this assertion will fail
assertThat(ringBearers).hasEntrySatisfying(oneRing, elfBearer);
Verifies that the actual map contains at least one of the given entries.
Example:
Map<Ring, TolkienCharacter> ringBearers = new HashMap<>();
ringBearers.put(nenya, galadriel);
ringBearers.put(narya, gandalf);
ringBearers.put(vilya, elrond);
ringBearers.put(oneRing, frodo);
// assertion will pass
assertThat(ringBearers).containsAnyOf(entry(oneRing, frodo), entry(oneRing, sauron));
// assertion will fail
assertThat(ringBearers).containsAnyOf(entry(oneRing, gandalf), entry(oneRing, aragorn));
Verifies that the actual number is not close to the given one by less than the given offset. If the difference is equal to the offset value, the assertion fails.
Example with int:
import static org.assertj.core.api.Assertions.byLessThan;
import static org.assertj.core.api.Assertions.withinPercentage;
// assertions will pass:
assertThat(5).isNotCloseTo(7, byLessThan(1));
assertThat(11).isNotCloseTo(10, withinPercentage(5));
// assertions will fail
assertThat(5).isNotCloseTo(7, byLessThan(2));
assertThat(5).isNotCloseTo(7, byLessThan(3));
assertThat(11).isNotCloseTo(10, withinPercentage(10));
assertThat(11).isNotCloseTo(10, withinPercentage(20));
Verifies that the actual CharSequence is blank, i.e. that it contains only whitespace characters. There are two variations of this assertion: isJavaBlank with whitespace defined by java Character#isWhitespace(char) and isBlank with whitespace defined according to the latest Unicode standard.
isNotBlank is (obviously) the opposite assertion of isBlank.
Examples:
// these assertions succeed:
assertThat(" ").isBlank();
assertThat(" ").isBlank();
assertThat("a").isNotBlank();
assertThat(" b").isNotBlank();
assertThat("").isNotBlank();
assertThat((String) null).isNotBlank();
// these ones fail:
assertThat("a").isBlank();
assertThat(" b").isBlank();
assertThat("").isBlank();
assertThat((String) null).isBlank();
assertThat(" ").isNotBlank();
assertThat(" ").isNotBlank();
Release date : 2016-07-03
Special thanks to Pascal Schumacher for his contributions including relentless code cleanup and documentation, thanks mate !
Many thanks to Dima Gerasimov, Nick Stolwijk, Ben Blank, Fabien Duminy, James Strachan, Johannes Brodwall and Kevin Fang for their contributions.
Extract specified properties/fields from each Iterable elements, group all of them into a single List that becomes the object under test.
Example :
Iterable<TolkienCharacter> fellowshipOfTheRing = ...
// flat extraction : all extracted values are put into a single list
assertThat(fellowshipOfTheRing).flatExtracting("name", "age", "race.name")
.contains("Boromir", 37, "Man",
"Sam", 38, "Hobbit",
"Legolas", 1000, "Elf");
// classic extraction :
// - needs a tuple to check values
// - stricter assertion -> using tuple("Legolas", 38, "Hobbit") would fail
assertThat(fellowshipOfTheRing).extracting("name", "age", "race.name")
.contains(tuple("Boromir", 37, "Man"),
tuple("Sam", 38, "Hobbit"),
tuple("Legolas", 1000, "Elf"));
The idea is to allow navigating to any Iterable element in order to perform assertions on it, which are Object assertions by default. If you want specific ones like String assertions you will have to provide the corresponding Assert class i.e. StringAssert (the reason being Java generics limitations).
Possible navigations:
Navigating back to the Iterable is not supported.
Examples :
Iterable<String> hobbitsNames = newArrayList("frodo", "sam", "pippin");
// Object assertions only (due to Java generics limitations)
assertThat(hobbitsNames).first()
.isEqualTo("frodo");
assertThat(hobbitsNames).element(1)
.isEqualTo("sam");
assertThat(hobbitsNames).last()
.isEqualTo("pippin");
// String assertions are possible if you specify the assert class
assertThat(hobbitsNames, StringAssert.class).first()
.startsWith("fro")
.endsWith("do");
assertThat(hobbitsNames, StringAssert.class).element(1)
.contains("a");
assertThat(hobbitsNames, StringAssert.class).last()
.endsWith("in");
It is now possible to navigate to an Iterable's size, perform Integer assertions on it and then navigate back to the Iterable to chain other assertions.
Example : instead of ...
Iterable<Ring> elvesRings = newArrayList(vilya, nenya, narya);
// can't chain size assertions with Iterable ones
assertThat(elvesRings.size()).isGreaterThan(1)
.isLessThanOrEqualTo(3)
assertThat(elvesRings).contains(narya)
.doesNotContain(oneRing);
... you can now write:
// all Integer assertions are available after size()
assertThat(elvesRings).size()
.isGreaterThan(1)
.isLessThanOrEqualTo(3)
.returnToIterable()
.contains(narya)
.doesNotContain(oneRing);
It is now possible to navigate to a Map's size, perform Integer assertions on it and then navigate back to the Map to chain other assertions.
Example : instead of ...
Map<Ring TolkienCharacter> ringBearers = new HashMap<>();
ringBearers.put(nenya, galadriel);
ringBearers.put(narya, gandalf);
ringBearers.put(oneRing, frodo);
// can't chain size assertions with Map ones
assertThat(ringBearers.size()).isGreaterThan(1)
.isLessThanOrEqualTo(3)
assertThat(ringBearers).containsKeys(oneRing, nenya, narya)
.containsEntry(oneRing, frodo);
... you can now write:
// all Integer assertions are available after size()
assertThat(ringBearers).size()
.isGreaterThan(1)
.isLessThanOrEqualTo(3)
.returnToMap()
.containsKeys(oneRing, nenya, narya)
.containsEntry(oneRing, frodo);
AssertJ relies on a Representation object to format types in error messages. Users can now register their own Representation either per assertion or globally (i.e. for all future assertions error messages).
Examples :
private class Example {} // dummy class
private class CustomRepresentation extends StandardRepresentation {
// override needed to hook non predefined type formatting
@Override
public String toStringOf(Object o) {
if (o instanceof Example) return "Example";
// fallback to default formatting.
return super.toStringOf(o);
}
// override a predefined type formatting : String
@Override
protected String toStringOf(String str) {
return "$" + str + "$";
}
}
Global scope custom representation :
// register CustomRepresentation only once
Assertions.useRepresentation(new CustomRepresentation());
// this assertion fails ...
assertThat(new Example()).isNull();
// ... with error :
expected:<[null]> but was:<[Example]>
// this one fails ...
assertThat("foo").startsWith("bar");
// ... with error :
Expecting:
<$foo$>
to start with:
<$bar$>
Per assertion scope custom representation :
// we need to register CustomRepresentation for each assertions
Representation customRepresentation = new CustomRepresentation();
// this assertion fails ...
assertThat(new Example()).withRepresentation(customRepresentation)
.isNull();
// ... with error :
expected:<[null]> but was:<[Example]>
// this one fails ...
assertThat("foo").withRepresentation(customRepresentation)
.startsWith("bar");
// ... with error :
Expecting:
<$foo$>
to start with:
<$bar$>
Verifies that the actual object has no Null fields or properties (inherited ones are taken into account) except the given ones (if any).
Example :
// all TolkienCharacter fields are set
TolkienCharacter frodo = new TolkienCharacter("Frodo", 33, HOBBIT);
assertThat(frodo).hasNoNullFieldsOrProperties();
// 'name' fields is not set
TolkienCharacter hobbitWithoutName = new TolkienCharacter(null, 38, HOBBIT);
assertThat(hobbitWithoutName).hasNoNullFieldsOrPropertiesExcept("name");
Several assertions related to URL and URI parameters have been added:
Examples :
// check parameter presence
assertThat(new URL("http://www.helloworld.org/index.html?happy")).hasParameter("happy");
assertThat(new URL("http://www.helloworld.org/index.html?happy=very")).hasParameter("happy");
// check parameter presence with expected value
assertThat(new URL("http://www.helloworld.org/index.html?happy")).hasParameter("happy", null);
assertThat(new URL("http://www.helloworld.org/index.html?happy=very")).hasParameter("happy", "very");
// check the absence of parameters
assertThat(new URL("http://www.helloworld.org/index.html")).hasNoParameters();
// check the absence of given parameter
assertThat(new URL("http://www.helloworld.org/index.html")).hasNoParameter("happy");
assertThat(new URL("http://www.helloworld.org/index.html")).hasNoParameter("happy", "very");
// check the absence of given parameter with the given value
assertThat(new URL("http://www.helloworld.org/index.html?happy")).hasNoParameter("happy", "very");
assertThat(new URL("http://www.helloworld.org/index.html?happy=very")).hasNoParameter("happy", null);
Use a recursive field/property by field/property comparison (including inherited fields/properties) instead of relying on actual type equals method to compare iterable/array elements for incoming assertion checks.
The recursive property/field comparison is not applied on fields having a custom equals implementation, i.e. the overridden equals method will be used instead of a field/property by field/property comparison.
The recursive comparison handles cycles.
You can specify a custom comparator per (nested) name or type of element field with usingComparatorForElementFieldsWithNames and usingComparatorForElementFieldsWithType.
The objects to compare can be of different types but must have the same properties/fields. For example if actual object has a name String field, the other object must also have one. If an object has a field and a property with the same name, the property value will be used over the field.
Example :
// setter, getters and constructor omitted
public class Dude {
String name;
double height;
Dude friend;
}
Dude jon = new Dude("Jon", 1.2);
Dude sam = new Dude("Sam", 1.3);
// introduce object graph cycle by mutual friendship
jon.friend = sam;
sam.friend = jon;
Dude jonClone = new Dude("Jon", 1.2);
Dude samClone = new Dude("Sam", 1.3);
jonClone.friend = samClone;
samClone.friend = jonClone;
// succeeds as jon, sam are equal to jonClone, samClone "by value"
assertThat(asList(jon, sam)).usingRecursiveFieldByFieldElementComparator()
.contains(jonClone, samClone);
Allows to set a comparator to compare properties or fields of elements of an array/iterable with the given type.
Comparators need to be specified by usingComparatorForElementFieldsWithType before calling any of:
Comparators specified by usingComparatorForElementFieldsWithNames have precedence over specified by this method.
Example :
// setter, getters and constructor omitted
public class Dude {
String name;
double height;
}
Dude dude = new Dude("Frodo", 1.2);
Dude tallerDude = new Dude("Frodo", 1.3);
List<Dude> hobbits = asList(dude);
// double are considered equals if they are close by less than 0.5
Comparator<Double> closeEnough = new AtPrecisionComparator<>(0.5);
assertThat(hobbits).usingComparatorForElementFieldsWithType(closeEnough, Double.class)
.usingFieldByFieldElementComparator()
.contains(tallerDude);
assertThat(hobbits).usingComparatorForElementFieldsWithType(closeEnough, Double.class)
.usingElementComparatorOnFields("height")
.contains(tallerDude);
assertThat(hobbits).usingComparatorForElementFieldsWithType(closeEnough, Double.class)
.usingElementComparatorIgnoringFields("name")
.contains(tallerDude);
assertThat(hobbits).usingComparatorForElementFieldsWithType(closeEnough, Double.class)
.usingRecursiveFieldByFieldElementComparator()
.contains(tallerDude);
Dude reallyTallDude = new Dude("Frodo", 1.9);
// assertion FAILS : 1.9 - 1.2 > 0.5
assertThat(asList(dude)).usingComparatorForElementFieldsWithType(closeEnough, Double.class)
.usingFieldByFieldElementComparator()
.contains(reallyTallDude);
Allows to set a comparator to compare properties or fields of elements of an array/iterable with the given names.
Comparators need to be specified by usingComparatorForElementFieldsWithNames before calling any of:
Comparators specified by this method have precedence over those by usingComparatorForElementFieldsWithType.
Example :
// setter, getters and constructor omitted
public class Dude {
String name;
double height;
}
Dude dude = new Dude("Frodo", 1.2);
Dude tallerDude = new Dude("Frodo", 1.3);
List<Dude> hobbits = asList(dude);
// double are considered equals if they are close by less than 0.5
Comparator<Double> closeEnough = new AtPrecisionComparator<>(0.5);
// assertions will pass
assertThat(hobbits).usingComparatorForElementFieldsWithNames(closeEnough, "height")
.usingFieldByFieldElementComparator()
.contains(tallerDude);
assertThat(hobbits).usingComparatorForElementFieldsWithNames(closeEnough, "height")
.usingElementComparatorOnFields("height")
.contains(tallerDude);
assertThat(hobbits).usingComparatorForElementFieldsWithNames(closeEnough, "height")
.usingElementComparatorIgnoringFields("name")
.contains(tallerDude);
assertThat(hobbits).usingComparatorForElementFieldsWithNames(closeEnough, "height")
.usingRecursiveFieldByFieldElementComparator()
.contains(tallerDude);
Dude reallyTallDude = new Dude("Frodo", 1.9);
// assertion FAILS : 1.9 - 1.2 > 0.5
assertThat(asList(dude)).usingComparatorForElementFieldsWithNames(closeEnough, "height")
.usingFieldByFieldElementComparator()
.contains(reallyTallDude);
isBetween verifies that the actual value is in the [start, end] range (start included, end included).
isStrictlyBetween verifies that the actual value is in the ]start, end[ range (start excluded, end excluded).
Example :
// assertions succeed :
assertThat('b').isBetween('a', 'b');
assertThat('b').isBetween('a', 'c');
assertThat('b').isStrictlyBetween('a', 'c');
// assertions fail :
assertThat('a').isStrictlyBetween('a', 'b');
assertThat('b').isStrictlyBetween('a', 'b');
The result of last soft assertion is now available from the method wasSuccess(). It can be used to decide what the next assertion should be. One noteworthy usage is to check the presence of some value before verifying it.
Example :
SoftAssertions soft = new SoftAssertions();
Person person = ... // query one Person
if (soft.assertThat(person).isNotNull().wasSuccess()) {
soft.assertThat(person.getAddress()).isNotNull();
}
Soft assertions acccumulated errors are now available with method errorsCollected().
Example :
SoftAssertions soft = new SoftAssertions();
soft.assertThat("foo").startsWith("boo");
assertThat(soft.errorsCollected()).hasSize(1);
soft.assertThat("bar").startsWith("far");
assertThat(soft.errorsCollected()).hasSize(2);
Release date : 2016-04-10
Thanks to Pascal Schumacher for his contribution.
Release date : 2016-03-30
This release includes all changes from AssertJ core 2.4.0 and adds some specific to Java 8.
Thanks to Pascal Schumacher and Grzegorz Piwowarek for their contributions.
isNotPresent is simply an alias of isEmpty assertion.
Example :
// assertion succeeds
assertThat(Optional.empty()).isNotPresent();
// assertion fails
assertThat(Optional.of("something")).isNotPresent();
isNotEmpty is simply an alias of isPresent assertion.
Example :
// assertion succeeds
assertThat(Optional.of("something")).isNotEmpty();
// assertion fails
assertThat(Optional.empty()).isNotEmpty();
withStackTraceContaining is used when starting exception assertions with assertThatExceptionOfType, it's an alternative of hasStackTraceContaining.
Example :
Throwable runtime = new RuntimeException("no way",
new Exception("you shall not pass"));
// assertion will pass
assertThatExceptionOfType(RuntimeException.class)
.isThrownBy(() -> {throw runtime;})
.withStackTraceContaining("you shall not pass");
Release date : 2016-03-28
Special thanks to Pascal Schumacher for his contributions including relentless code cleanup and documentation, thanks buddy !
Many thanks also to Michaël Bitard, Michael W. Fender, Lovro Pandzic, Peter Phillips and Daniel Zlotin for their contributions.
Recursive comparison is based on java-util deepEquals by John DeRegnaucourt and Ken Partlow, thanks to them !
Assert that the object under test (actual) is equal to the given object based on recursive a property/field by property/field comparison (including inherited ones), the recursive property/field comparison is not applied on fields having a custom equals implementation, i.e. the overriden equals method will be used instead of a field by field comparison.
The recursive comparison handles cycle, by default it compares floats with a precision of 1.0E-6 and doubles with 1.0E-15.
You can specify a custom comparator per (nested) fields or type with respectively usingComparatorForFields(Comparator, String...) and usingComparatorForType(Comparator, Class).
The objects to compare can be of different types but must have the same properties/fields. For example if the actual object has a name String field, it is expected that the other object also has one. If an object has a field and a property with the same name, the property value will be used over the field.
Example :
// classes with public fields for brevity
public class Person {
public String name;
public double height;
public Home home = new Home();
public Person bestFriend;
// constructor with name and height omitted for brevity's sake
}
public class Home {
public Address address = new Address();
}
public static class Address {
public int number = 1;
}
Person jack = new Person("Jack", 1.80);
jack.home.address.number = 123;
Person jackClone = new Person("Jack", 1.80);
jackClone.home.address.number = 123;
// cycle are handled in comparison
jack.bestFriend = jackClone;
jackClone.bestFriend = jack;
// will fail as equals compares object references
assertThat(jack).isEqualsTo(jackClone);
// jack and jackClone are equal when doing a recursive field by field comparison
assertThat(jack).isEqualToComparingFieldByFieldRecursively(jackClone);
// any type/field can be compared with a a specific comparator.
// let's change jack's height a little bit
jack.height = 1.81;
// assertion fails because of the height difference
// (the default precision comparison for double is 1.0E-15)
assertThat(jack).isEqualToComparingFieldByFieldRecursively(jackClone);
// use usingComparatorForType to specify how to compare the given type
// assertion succeeds because we allow a 0.5 tolerance on double
assertThat(jack).usingComparatorForType(new DoubleComparator(0.5), Double.class)
.isEqualToComparingFieldByFieldRecursively(jackClone);
// use usingComparatorForFields to specify how to compare some fields (nested fields are supported)
assertThat(jack).usingComparatorForFields(new DoubleComparator(0.5), "height")
.isEqualToComparingFieldByFieldRecursively(jackClone);
Allows to set a specific comparator to compare properties or fields of the given type. A typical usage is for comparing numbers fields with a given precision. Comparators specified by usingComparatorForFields have precedence over comparators specified by this method.
Example :
public class TolkienCharacter {
private String name;
private double height;
// boilerplate code omitted
}
TolkienCharacter frodo = new TolkienCharacter("Frodo", 1.2);
TolkienCharacter tallerFrodo = new TolkienCharacter("Frodo", 1.3);
TolkienCharacter reallyTallFrodo = new TolkienCharacter("Frodo", 2.0);
Comparator<Double> closeEnough = new Comparator<Double>() {
double precision = 0.5;
public int compare(Double d1, Double d2) {
return Math.abs(d1 - d2) <= precision ? 0 : 1;
}
};
// assertions will pass
assertThat(frodo).usingComparatorForType(closeEnough, Double.class)
.isEqualToComparingFieldByField(tallerFrodo);
assertThat(frodo).usingComparatorForType(closeEnough, Double.class)
.isEqualToIgnoringNullFields(tallerFrodo);
assertThat(frodo).usingComparatorForType(closeEnough, Double.class)
.isEqualToIgnoringGivenFields(tallerFrodo);
assertThat(frodo).usingComparatorForType(closeEnough, Double.class)
.isEqualToComparingOnlyGivenFields(tallerFrodo);
// assertion will fail
assertThat(frodo).usingComparatorForType(closeEnough, Double.class)
.isEqualToComparingFieldByField(reallyTallFrodo);
Allows to set a specific comparator to compare properties or fields with the given names. A typical usage is for comparing double/float fields with a given precision. Comparators specified by this method have precedence over comparators specified by usingComparatorForType.
Example :
public class TolkienCharacter {
private String name;
private double height;
// boilerplate code omitted
}
TolkienCharacter frodo = new TolkienCharacter("Frodo", 1.2);
TolkienCharacter tallerFrodo = new TolkienCharacter("Frodo", 1.3);
TolkienCharacter reallyTallFrodo = new TolkienCharacter("Frodo", 2.0);
Comparator<Double> closeEnough = new Comparator<Double>() {
double precision = 0.5;
public int compare(Double d1, Double d2) {
return Math.abs(d1 - d2) <= precision ? 0 : 1;
}
};
// assertions succeed (it is possible to specify multiple fields)
assertThat(frodo).usingComparatorForFields(closeEnough, "height")
.isEqualToComparingFieldByField(tallerFrodo);
assertThat(frodo).usingComparatorForFields(closeEnough, "height")
.isEqualToIgnoringNullFields(tallerFrodo);
assertThat(frodo).usingComparatorForFields(closeEnough, "height")
.isEqualToIgnoringGivenFields(tallerFrodo);
assertThat(frodo).usingComparatorForFields(closeEnough, "height")
.isEqualToComparingOnlyGivenFields(tallerFrodo);
// assertion fails
assertThat(frodo).usingComparatorForFields(closeEnough, "height")
.isEqualToComparingFieldByField(reallyTallFrodo);
Verifies that the content of the actual File/Path is the same as the given one, the expected File/Path being read with the given charset while the charset used to read the actual path can be provided with usingCharset(Charset/String)prior to calling this method; if not, the platform's default charset will be used.
Example :
Set<String> lines = Collections.singleton("Gerçek");
Path utf8File = Files.write(Paths.get("actual"), lines, StandardCharsets.UTF_8);
Charset turkishCharset = Charset.forName("windows-1254");
Path turkishFile = Files.write(Paths.get("expected"), lines, turkishCharset);
// The following assertion succeeds:
assertThat(utf8File).usingCharset(StandardCharsets.UTF_8)
.hasSameContentAs(turkishFile, turkishCharset);
// The following assertion fails:
assertThat(utf8File).usingCharset(StandardCharsets.UTF_8)
.hasSameContentAs(turkishFile, StandardCharsets.UTF_8);
Verifies that the actual group (Iterable or object array) contains exactly the given values and nothing else, in any order. The difference with containsOnly is that containsOnly does not enforce duplicates elements as containsExactlyInAnyOrder does.
Example :
// note that vilya appears twice
Iterable<Ring> elvesRings = newArrayList(vilya, nenya, narya, vilya);
// assertion succeeds as elements order does not matter
assertThat(elvesRings).containsExactlyInAnyOrder(vilya, vilya, nenya, narya);
// assertion fails as vilya is contained twice in elvesRings.
assertThat(elvesRings).containsExactlyInAnyOrder(nenya, vilya, narya);
// but containsOnly succeeds as it does not enforce duplicates elements
assertThat(elvesRings).containsOnly(nenya, vilya, narya);
Release date : 2016-01-10
This release includes all changes from AssertJ core 2.3.0 and additional ones specific to Java 8.
Thanks to Pascal Schumacher, Chris Arnott, Jeremy Landis, Trond Marius Øvstetun and Misha Brukman for their contributions.
assertThat(myStream) simply converts myStream to a List thus providing all List assertions.
Please note that the Stream is consumed and cannot be used again (unless you chain assertions).
Example :
Stream<TolkienCharacter> fellowshipOfTheRing = Stream.of(frodo, sam, pippin, boromir,
legolas, gandalf, gimli);
// all List assertion are available
assertThat(fellowshipOfTheRing).contains(frodo)
.doesNotContain(sauron);
.extracting(TolkienCharacter::getRace)
.contains(HOBBIT, ELF)
.doesNotContain(ORC);
// WARNING : this assertion is not possible as fellowshipOfTheRing was already consumed.
assertThat(fellowshipOfTheRing).contains(frodo);
Verifies that all elements of the actual Iterable or Object[] match the given Predicate.
Example :
// also works with hobbits defined as an Iterable<TolkienCharacter>
TolkienCharacter[] hobbits = { frodo, sam, pippin };
assertThat(hobbits).allMatch(character -> character.getRace() == HOBBIT);
It was already possible to extract multiple values by name (using introspection), it is now possible to pass lambda functions to extract the values to check.
Example :
TolkienCharacter[] fellowshipOfTheRing = { frodo, sam, pippin, boromir, legolas, gandalf, gimli };
// TolkienCharacter age is public
assertThat(fellowshipOfTheRingArray).extracting(TolkienCharacter::getName,
tolkienCharacter -> tolkienCharacter.age)
.contains(tuple("Boromir", 37),
tuple("Sam", 38),
tuple("Legolas", 1000));
It was already possible to extract multiple values by name (using introspection), it is now possible to pass lambda functions to extract the values to check.
Example :
TolkienCharacter[] fellowshipOfTheRing = { frodo, sam, pippin, boromir, legolas, gandalf, gimli };
// TolkienCharacter age is public
assertThat(fellowshipOfTheRingArray).extracting(TolkienCharacter::getName,
tolkienCharacter -> tolkienCharacter.age)
.contains(tuple("Boromir", 37),
tuple("Sam", 38),
tuple("Legolas", 1000));
Using lamdas functions, extract values from the object under test into an array, this new array becoming the object under test. (similar to extracting taking fields/properties names)
Example :
TolkienCharacter frodo = new TolkienCharacter("Frodo", 33, HOBBIT);
assertThat(frodo).extracting(TolkienCharacter::getName,
character -> character.age,
character -> character.getRace().getName())
.containsExactly("Frodo", 33, "Hobbit");
Verifies that the actual Optional contains a value and gives this value to the given Consumer for further assertions allowing deeper assertions on the containing object.
Example :
// one requirement
assertThat(Optional.of(10)).hasValueSatisfying(i -> { assertThat(i).isGreaterThan(9); });
// multiple requirements
assertThat(Optional.of("something")).hasValueSatisfying(s -> {
assertThat(s).startsWith("some");
assertThat(s).endsWith("thing");
assertThat(s).isEqualTo("something");
});
// failing assertion as the Optional does not have a value.
assertThat(Optional.empty()).hasValueSatisfying(i -> { assertThat(i).isEqualTo("something"); });
Verifies that the actual LocalDate is today, that is matching current year, month and day.
Example :
// assertion will pass
assertThat(LocalDate.now()).isToday();
// assertion will fail
assertThat(theFellowshipOfTheRin ReleaseDate()).isToday();
Some users prefer assertThatExceptionOfType over assertThatThrownBy to check exceptions, it is now possible to check the exception message specifying the expected value using String#format syntax.
Example :
assertThatExceptionOfType(IOException.class)
.isThrownBy(() -> { throw new Exception("boom !"); })
.withMessage("%s !", "boom");
Allow to check that an Optional value is the same as a given one.
Example :
Player ginobili = new Player("Manu Ginobili");
assertThat(Optional.of(ginobili)).containsSame(ginobili);
Release date : 2016-01-02
Special thanks to Pascal Schumacher for his contributions including relentless code cleanup and improvements, appreciated !
Many thanks also to Pierre Templier, Guillaume Husta, Libor Ondrušek, Dan Corder and Chris Arnott for their contributions.
This release tried to make AssertJ Core usable for testing Android applications (by introducing Java6Assertions) but this has not been reliably verified so any feedback is welcome.
AssertJ has used part of java-diff-utils code to produce better diff content, thanks to Dmitry Naumenko its creator !
Extract the values of given fields/properties from the object under test into an array, this new array becoming the object under test.
Example :
// Create frodo, setting its name, age and Race fields (Race having a name field)
TolkienCharacter frodo = new TolkienCharacter("Frodo", 33, HOBBIT);
// let's verify Frodo's name, age and race name:
assertThat(frodo).extracting("name", "age", "race.name")
.containsExactly("Frodo", 33, "Hobbit");
hasFieldOrProperty : assert that the actual object has the specified field or property.
hasFieldOrPropertyWithValue : assert that the actual object has the specified field or property with the given value.
Example :
// Create frodo, setting its name, age and Race fields (Race having a name field)
TolkienCharacter frodo = new TolkienCharacter("Frodo", 33, HOBBIT);
// let's verify Frodo's age and race name:
assertThat(frodo).hasFieldOrProperty("age")
.hasFieldOrProperty("race.name")
.hasFieldOrPropertyWithValue("age", 33)
.hasFieldOrPropertyWithValue("race.name", "Hobbit");
Verifies that a String contains the given regular expression.
Example :
// you can use a Pattern or a String to define the regex to find.
assertThat("Frodo").containsPattern("Fr.d");
assertThat("Frodo").containsPattern(Pattern.compile("Fr.d"));
Verifies that the Map under test contains all entries of the given Map.
Example :
Map<Ring, TolkienCharacter> ringBearers = new HashMap<>();
ringBearers.put(nenya, galadriel);
ringBearers.put(narya, gandalf);
ringBearers.put(vilya, elrond);
ringBearers.put(oneRing, frodo);
Map<Ring, TolkienCharacter> elvesRingBearers = new HashMap<>();
elvesRingBearers.put(nenya, galadriel);
elvesRingBearers.put(narya, gandalf);
elvesRingBearers.put(vilya, elrond);
// assertion succeeds
assertThat(ringBearers).containsAllEntriesOf(elvesRingBearers);
All double[] and float[] assertions can now be performed with a given precision to compare numbers.
Example with contains assertion for double[]:
import static org.assertj.core.api.Assertions.withPrecision;
double[] values = new double[] { 1.0, 2.0, 3.0 };
// assertion succeeds
assertThat(values).contains(new double[] {1.01, 3.01, 2.0}, withPrecision(0.02));
// assertion fails
assertThat(values).contains(new double[] {1.0, 4.0}, withPrecision(0.5));
Note that you can also use usingComparatorWithPrecision to achieve the same result:
double[] values = new double[] { 1.0, 2.0, 3.0 };
// assertion succeeds
assertThat(values).usingComparatorWithPrecision(0.5)
.contains(1.1, 2.1);
Verifies that the Iterable under test contains a subset of the given values.
Example :
List<Ring> elvesRings = newArrayList(vilya, nenya, narya);
// assertion succeeds
assertThat(elvesRings).isSubsetOf(oneRing, vilya, nenya, narya);
Verifies the message of an Exception using String#format syntax.
Example :
try {
List<String> abc = newArrayList("a", "b", "c");
abc.get(4);
} catch (Exception e) {
assertThat(e).hasMessage("Index: %s, Size: %s", 4, 3);
}
Files (or InputStreams) content comparison is smarter, much like version control diff thanks to java-diff-utils.
Example :
// writeFile takes file name and file content parameters
File actual = writeFile("actual.txt", "aaaaaa\n" +
"bbbbbb\n" +
"cccccc\n" +
"dddddd\n");
File expected = writeFile("expected.txt", "------\n" +
"aaaaaa\n" +
"bbbbbb\n" +
"CCCCCC\n" +
"dddddd\n" +
"eeeeee\n");
// assertion fails
assertThat(actual).hasSameContentAs(expected);
The previous assertion fails with the following error message:
File:
<.../actual>
and file:
<.../expected>
do not have same content:
Missing content at line 1:
["------"]
Changed content at line 4:
expecting:
["CCCCCC"]
but was:
["cccccc"]
Missing content at line 6:
["eeeeee"]
Release date : 2015-09-21
This release includes all changes from AssertJ core 2.2.0 and additional ones specific to Java 8.
Thanks to Richard Lucas, Tobias Bieniek, Clément Mathieu and Nicolai Parlog for their contributions.
Provide assertions for Java 8 CompletableFuture.
Note that hasFailed() is a shortcut for isCompletedExceptionally() and isNotCancelled().
Example :
// completed future
CompletableFuture<String> completedFuture = CompletableFuture.completedFuture("something");
assertThat(completedFuture).isCompleted()
.isCompletedWithValue("something")
.isCompletedWithValueMatching(val -> val.startsWith("some"))
.isDone();
// cancelled future
CompletableFuture<?> cancelledFuture = new CompletableFuture<>();
cancelledFuture.cancel(true);
assertThat(cancelledFuture).isCancelled()
.isDone()
.hasNotFailed();
// future completed exceptionally
CompletableFuture<?> futureExplosion = new CompletableFuture<>();
futureExplosion.completeExceptionally(new RuntimeException("boom !"));
assertThat(futureExplosion).isCompletedExceptionally()
.isDone();
// failed future = isCompletedExceptionally() + isNotCancelled()
assertThat(futureExplosion).hasFailed()
.hasFailedWithThrowableThat() // allow to chain exception assertions
.isInstanceOf(RuntimeException.class)
.hasMessage("boom !");
Provide like contains a way to check Optional value.
Example :
assertThat(Optional.of("Yoda")).hasValue("Yoda");
// same assertion using contains
assertThat(Optional.of("Yoda")).contains("Yoda");
Provide a way to check Optional value with a specific comparator.
Example :
// comparator implementation omitted
Comparator<String> caseInsensitiveStringComparator = ...;
assertThat(Optional.of("YODA")).usingValueComparator(caseInsensitiveStringComparator)
.hasValue("yoda");
Allow to check that an Optional value is the same as a given one.
Example :
Player ginobili = new Player("Manu Ginobili");
assertThat(Optional.of(ginobili)).containsSame(ginobili);
Release date : 2015-09-03
Thanks to Libor Ondrušek, Pascal Schumacher and Alexander Bischof for their contributions.
Release date : 2015-06-25
This release include all changes from AssertJ core 2.1.0 and provides new ones specific to Java 8.
Thanks to Alexander Bischof, Mariusz Smykuła and Alban Dericbourg for their contributions.
AssertJ fluent filtering for collection/arrays has been improved to express the filter condition with a Predicate.
Example :
assertThat(fellowshipOfTheRing).filteredOn( character -> character.getName().contains("o") )
.containsOnly(aragorn, frodo, legolas, boromir);
Provide assertions for OffsetDateTime. Most of the assertions come with a String based parameter equivalent that will be parsed into a OffsetDateTime, the examples shown below use this possiblity for brevity sake's.
Examples :
OffsetDateTime firstOfJanuary2000InUTC = OffsetDateTime.parse("2000-01-01T00:00:00Z");
assertThat(firstOfJanuary2000InUTC).isEqualTo(OffsetDateTime.parse("2000-01-01T00:00:00Z"));
// same assertion but AssertJ takes care of expected String to OffsetDateTime conversion
assertThat(firstOfJanuary2000InUTC).isEqualTo("2000-01-01T00:00:00Z");
assertThat(firstOfJanuary2000InUTC).isAfter("1999-12-31T23:59:59Z");
// assertion succeeds as OffsetDateTime are compared in actual's time zone
// 2000-01-01T00:30:00+01:00 = 1999-12-31T23:30:00Z
assertThat(firstOfJanuary2000InUTC).isAfter("2000-01-01T00:30:00+01:00")
.isAfterOrEqualTo("1999-12-31T23:59:59Z")
.isAfterOrEqualTo("2000-01-01T00:00:00Z");
assertThat(firstOfJanuary2000InUTC).isBefore("2000-01-01T00:00:01Z")
.isBeforeOrEqualTo("2000-01-01T00:00:01Z")
.isBeforeOrEqualTo("2000-01-01T00:00:00Z");
OffsetDateTime offsetDateTime1 = OffsetDateTime.of(2000, 1, 1, 0, 0, 0, 0, ZoneOffset.UTC);
OffsetDateTime offsetDateTime2 = OffsetDateTime.of(2000, 1, 1, 23, 59, 59, 999, ZoneOffset.UTC);
OffsetDateTime offsetDateTime3 = OffsetDateTime.of(2000, 1, 1, 0, 59, 59, 999, ZoneOffset.UTC);
OffsetDateTime offsetDateTime4 = OffsetDateTime.of(2000, 1, 1, 0, 0, 59, 999, ZoneOffset.UTC);
OffsetDateTime offsetDateTime5 = OffsetDateTime.of(2000, 1, 1, 0, 0, 0, 999, ZoneOffset.UTC);
// comparison with a precision level
assertThat(offsetDateTime1).isEqualToIgnoringHours(offsetDateTime2);
assertThat(offsetDateTime1).isEqualToIgnoringMinutes(offsetDateTime3);
assertThat(offsetDateTime1).isEqualToIgnoringSeconds(offsetDateTime4);
assertThat(offsetDateTime1).isEqualToIgnoringNanos(offsetDateTime5);
Provide assertions for OffsetTime. Most of the assertions come with a String based parameter equivalent that will be parsed into a OffsetTime, the examples shown below use this possiblity for brevity sake's.
Examples :
OffsetTime oneAm = OffsetTime.parse("01:00:00+02:00");
assertThat(oneAm).isEqualTo("01:00:00+02:00");
assertThat(oneAm).isAfter("00:00:00+02:00")
.isAfterOrEqualTo("00:00:00+02:00")
.isAfterOrEqualTo("01:00:00+02:00");
assertThat(oneAm).isBefore("02:00:00+02:00")
.isBeforeOrEqualTo("02:00:00+02:00")
.isBeforeOrEqualTo("01:00:00+02:00");
Add assertions for OptionalInt, OptionalLong and OptionalDouble.
Examples :
OptionalInt optional = OptionalInt.of(12);
assertThat(optional).isPresent()
.hasValue(12);
OptionalDouble emptyOptional = OptionalDouble.empty();
assertThat(emptyOptional).isEmpty();
Allow to check the of type Optional value.
Example :
Optional<String>> optional = Optional.of("Test");
assertThat(optional).containsInstanceOf(String.class);
Release date : 2015-06-10
Thanks to Michal Kordas, Kamil Szymanski, Paul Dorzey and Alexander Bischof for their contributions.
It was already possible to filter iterable/array but not in current assertion flow, it is now possible to combine iterable/array assertion and filtering in a fluent way.
You can filter on a property/field or using a Condition.
Filtering on a property or a field
You specify first the property/field name to filter on and its expected value. The filter first tries to get the value from a property, then from a field. Reading private fields is supported by default, this can be globally disabled by calling Assertions.setAllowExtractingPrivateFields(false).
Filters supports reading nested property/field, not that if an intermediate value is null the whole nested property/field is considered to be null, thus reading "address.street.name" value will return null if "address.street" value is null.
Filters support basic operation : not, in, notIn
As an example, let's check all employees 800 years old :
Employee yoda = new Employee(1L, new Name("Yoda"), 800);
Employee obiwan = new Employee(2L, new Name("Obiwan"), 800);
Employee luke = new Employee(3L, new Name("Luke", "Skywalker"), 26);
List<Employee> employees = newArrayList(yoda, luke, obiwan);
// filter employees before performing an assertion
assertThat(employees).filteredOn("age", 800)
.containsOnly(yoda, obiwan);
// it supports nested property/field
assertThat(employees).filteredOn("name.first", "Luke")
.containsOnly(luke);
// to filter on null value just use filterOnNull
assertThat(employees).filteredOnNull("name.last")
.containsOnly(yoda, obiwan, noname);
Filters support basic operation : not, in, notIn
import static org.assertj.core.api.Assertions.in;
import static org.assertj.core.api.Assertions.not;
import static org.assertj.core.api.Assertions.notIn;
...
assertThat(employees).filteredOn("age", not(800))
.containsOnly(luke);
// Name is bean class with 'first' and 'last' String properties
assertThat(employees).filteredOn("name.first", in("Yoda", "Luke"))
.containsOnly(yoda, luke);
assertThat(employees).filteredOn("name.first", notIn("Yoda", "Luke"))
.containsOnly(obiwan);
You can chain filters :
// fellowshipOfTheRing is a list of TolkienCharacter having race and name fields
// 'not' filter is statically imported from Assertions.not
assertThat(fellowshipOfTheRing).filteredOn("race.name", "Man")
.filteredOn("name", not("Boromir"))
.containsOnly(aragorn);
Filtering with a Condition
Filter the iterable/array under test keeping only elements matching the given Condition.
As an example, let's check all employees whose age > 100 :
// old employee condition, "old employees" describes the condition in error message
// you just have to implement a 'matches' method
Condition<Employee> oldEmployees = new Condition<Employee>("old employees") {
@Override
public boolean matches(Employee employee) {
return employee.getAge() > 100;
}
};
// use oldEmployees Condition to express filter predicate
assertThat(employees).filteredOn(oldEmployees)
.containsOnly(yoda, obiwan);
// You can combine Conditions with condition operators like Not:
assertThat(employees).filteredOn(not(oldEmployees))
.containsOnly(luke);
New assertions for URI and URL.
URI assertions examples :
assertThat(new URI("http://assertj.org:8080/news.html#print")).hasHost("assertj.org")
.hasPort(8080)
.hasPath("/news.html")
.hasFragment("print");
assertThat(new URI("http://assertj.org")).hasNoFragment()
.hasNoPort()
.hasPath("")
.hasNoQuery()
.hasNoUserInfo();
assertThat(new URI("mailto:java-net@java.sun.com")).hasNoPath();
assertThat(new URI("http://test:pass@www.helloworld.org/index.html")).hasUserInfo("test:pass");
assertThat(new URI("http://test@www.helloworld.org/index.html")).hasUserInfo("test");
assertThat(new URI("http://:pass@www.helloworld.org/index.html")).hasUserInfo(":pass");
URL assertions examples :
assertThat(new URL("http://assertj.org:8080/news.html#print")).hasHost("assertj.org")
.hasPort(8080)
.hasPath("/news.html")
.hasAnchor("print");
assertThat(new URL("http://assertj.org")).hasNoAnchor()
.hasNoPath()
.hasNoPort()
.hasNoQuery()
.hasNoUserInfo();
assertThat(new URL("http://helloworld.org")).hasAuthority("helloworld.org");
Verifies that the actual number is close to the given one within the given percentage. If difference is equal to the percentage value, assertion is considered valid.
You can express percentage with Assertions.withinPercentage
Example :
import static org.assertj.core.api.Assertions.withinPercentage;
...
// assertions will pass:
assertThat(5.0).isCloseTo(6.0, withinPercentage(20.0));
assertThat(5).isCloseTo(6, withinPercentage(20));
// assertion will fail
assertThat(11).isCloseTo(10, withinPercentage(5));
Verifies that the actual value is equal to the given one by invoking Comparable.compareTo(Object).
isEqualByComparingTo verifies that the actual value is equal to the given one by invoking Comparable.compareTo(Object), isNotEqualByComparingTo does the opposite.
Example :
// assertion will pass because 8.0 is equal to 8.00 using BigDecimal.compareTo(BigDecimal)
assertThat(new BigDecimal("8.0")).isEqualByComparingTo(new BigDecimal("8.00"));
assertThat(new BigDecimal(1.0)).isNotEqualByComparingTo(new BigDecimal(2.0));
Verifies that the actual actual.toString() is equal to the given String.
Example :
CartoonCaracter homer = new CartoonCaracter("Homer");
// Instead of writing ...
assertThat(homer.toString()).isEqualTo("Homer");
// ... you can simply write:
assertThat(homer).hasToString("Homer");
Verifies that the actual Date represents the same time as the given date in String format.
It is the same assertion as hasSameTimeAs(Date) but given date is represented as String
Example :
Date date = parseDatetime("2003-04-26T12:00:00");
// assertion will pass
assertThat(date).hasSameTimeAs("2003-04-26T12:00:00");
// assertion will fail
assertThat(date).hasSameTimeAs("2003-04-26T12:00:01");
assertThat(date).hasSameTimeAs("2003-04-27T12:00:00");
Default date formats (expressed in the local time zone) are:
Verifies that the actual String does not start/end with the given String.
Example :
// assertions will pass
assertThat("Gandalf the grey").doesNotStartWith("grey");
.doesNotEndWith("Gan");
contains(Iterable)
Verifies that the actual String contains all the strings of the given Iterable.
Example :
assertThat("Gandalf the grey").contains(Arrays.asList("alf"));
assertThat("Gandalf the grey").contains(Arrays.asList("alf", "grey"));
containsSequence(Iterable)
Verifies that the actual String contains all the strings of the given Iterable in the Iterable iteration order.
Example :
assertThat("Gandalf the grey").contains(Arrays.asList("alf"));
assertThat("Gandalf the grey").contains(Arrays.asList("alf", "grey"));
Example :
// assertions will pass
assertThat(" my foo bar ").isEqualToIgnoringWhitespace("my foo bar");
assertThat("my foo bar").isEqualToIgnoringWhitespace("my foo bar");
assertThat(" my foo bar ").isEqualToIgnoringWhitespace("my foo bar");
assertThat(" my\tfoo bar ").isEqualToIgnoringWhitespace(" my foo bar");
assertThat("my foo bar").isEqualToIgnoringWhitespace(" my foo bar ");
// assertion will fail due to the space between foo and bar
assertThat(" my\tfoo bar ").isEqualToIgnoringWhitespace(" my foobar");
Verifies that the actual String is not equal to the given one, ignoring case considerations.
Example :
// assertion will pass
assertThat("Gandalf").isNotEqualToIgnoringCase("Hobbit");
// assertions will fail
assertThat("Gandalf").isNotEqualToIgnoringCase("Gandalf");
assertThat("Gandalf").isNotEqualToIgnoringCase("GaNDalf");
Iterable/array in error messages will be formatted on a single lines if the overall description is < 80 characters, otherwise it will formatted on multiple lines with one element per line.
You can set the line maxlength threshold with Assertions.setMaxLengthForSingleLineDescription
Example :
// this array ...
String[] greatBooks = array("A Game of Thrones", "The Lord of the Rings", "Assassin's Apprentice");
// ... is formatted on one line:
["A Game of Thrones", "The Lord of the Rings", "Assassin's Apprentice"]
// whereas this one ...
String[] greatBooks = array("A Game of Thrones", "The Lord of the Rings", "Assassin's Apprentice", "Guards! Guards! (Discworld)");
// ... is formatted on multiple lines (one element per line):
["A Game of Thrones",
"The Lord of the Rings",
"Assassin's Apprentice",
"Guards! Guards! (Discworld)"]
Instead of having to implement an Extractor, you can use a String to specify the Iterable or array to extract and then flatten.
Example :
// the Simpsons
CartoonCharacter bart = new CartoonCharacter("Bart Simpson");
CartoonCharacter lisa = new CartoonCharacter("Lisa Simpson");
CartoonCharacter maggie = new CartoonCharacter("Maggie Simpson");
CartoonCharacter homer = new CartoonCharacter("Homer Simpson");
homer.addChildren(bart, lisa, maggie);
// the Flintstones
CartoonCharacter pebbles = new CartoonCharacter("Pebbles Flintstone");
CartoonCharacter fred = new CartoonCharacter("Fred Flintstone");
fred.getChildren().add(pebbles);
// extract children list and flatten them in one list
List<CartoonCharacter> parents = newArrayList(homer, fred);
assertThat(parents).flatExtracting("children")
.containsOnly(bart, lisa, maggie, pebbles);
Allow to check that a String contains only digit (but not that string is a valid number representation !).
Example :
// assertion will pass:
assertThat("321").containsOnlyDigits();
// assertion will fail:
assertThat("321.0").containsOnlyDigits();
Add isCloseTo primitive approximation assertion for long, int, short and byte, it relies on within method to express the allowed approximation which can be statically imported from org.assertj.core.api.Assertions.
Example :
import static org.assertj.core.api.Assertions.within;
...
// assertion will pass:
assertThat(5).isCloseTo(7, within(3));
// if difference is exactly equals to the offset, it's ok
assertThat(5).isCloseTo(7, within(2));
// assertion will fail:
assertThat(5).isCloseTo(7, within(1));
Verifies that the actual Class is final (has final modifier) or not.
Example :
assertThat(String.class).isFinal();
assertThat(Throwable.class).isNotFinal();
Release date : 2015-04-06
This is the first release that provides assertions for Java 8.
Thanks to Brice Dutheil, Jean-Christophe Gay, zdanek and Marcin Zajączkowski for their contributions.
AssertJ provides assertions for ZonedDateTime, LocalDateTime, LocalDate and LocalTime. Most of the assertions come with a String based parameter equivalent that will be parsed into the expected date/time type, the examples shown below use this possiblity for brevity sake's.
Note that for ZonedDateTime assertions, comparison is performed in actual's time zone.
Comparing date/time ignoring some fields only checks that the non-ignored fields are equal. The ignored fields are those below (or equal) to the given precision, for example ignoring minutes means that minutes, seconds and nanoseconds will be ignored. It is also important to understand that the time difference does not count, it turns out that, as in the example below, two date/time can have only 1 ns difference with different minutes, seconds and nanoseconds fields.
LocalDateTime localDateTimeA = LocalDateTime.of(2000, 1, 1, 23, 50, 00, 000);
LocalDateTime localDateTimeB = LocalDateTime.of(2000, 1, 1, 23, 49, 59, 999999999);
// assertion fails as minute fields differ even if time difference is only 1ns
assertThat(localDateTimeA).isEqualToIgnoringSeconds(localDateTimeB);
LocalDate examples :
LocalDate firstOfJanuary2000 = LocalDate.parse("2000-01-01");
// AssertJ converts String parameters to LocalDate to ease writing expected LocalDate
assertThat(firstOfJanuary2000).isEqualTo("2000-01-01");
assertThat(firstOfJanuary2000).isAfter("1999-12-31")
.isAfterOrEqualTo("1999-12-31")
.isAfterOrEqualTo("2000-01-01");
assertThat(firstOfJanuary2000).isBefore("2000-01-02")
.isBeforeOrEqualTo("2000-01-02")
.isBeforeOrEqualTo("2000-01-01");
LocalTime examples :
LocalTime oneAm = LocalTime.parse("01:00:00");
// AssertJ converts String parameters to LocalTime to ease writing expected LocalTime
assertThat(oneAm).isEqualTo("01:00:00");
assertThat(oneAm).isAfter("00:00:00")
.isAfterOrEqualTo("00:00:00")
.isAfterOrEqualTo("01:00:00");
assertThat(oneAm).isBefore("02:00:00")
.isBeforeOrEqualTo("02:00:00")
.isBeforeOrEqualTo("01:00:00");
LocalDateTime examples :
LocalDateTime firstOfJanuary2000 = LocalDateTime.parse("2000-01-01T00:00:00");
// AssertJ converts String parameters to LocalDateTime to ease writing expected LocalDateTime
assertThat(firstOfJanuary2000).isEqualTo("2000-01-01T00:00:00");
assertThat(firstOfJanuary2000).isAfter("1999-12-31T23:59:59")
.isAfterOrEqualTo("1999-12-31T23:59:59")
.isAfterOrEqualTo("2000-01-01T00:00:00");
assertThat(firstOfJanuary2000).isBefore("2000-01-01T00:00:01")
.isBeforeOrEqualTo("2000-01-01T00:00:01")
.isBeforeOrEqualTo("2000-01-01T00:00:00");
// successful assertions ignoring ...
// ... nanoseconds
LocalDateTime localDateTime1 = LocalDateTime.of(2000, 1, 1, 0, 0, 1, 0);
LocalDateTime localDateTime2 = LocalDateTime.of(2000, 1, 1, 0, 0, 1, 456);
assertThat(localDateTime1).isEqualToIgnoringNanos(localDateTime2);
// ... seconds
localDateTime1 = LocalDateTime.of(2000, 1, 1, 23, 50, 0, 0);
localDateTime2 = LocalDateTime.of(2000, 1, 1, 23, 50, 10, 456);
assertThat(localDateTime1).isEqualToIgnoringSeconds(localDateTime2);
// ... minutes
localDateTime1 = LocalDateTime.of(2000, 1, 1, 23, 50, 0, 0);
localDateTime2 = LocalDateTime.of(2000, 1, 1, 23, 00, 2, 7);
assertThat(localDateTime1).isEqualToIgnoringMinutes(localDateTime2);
// ... hours
localDateTime1 = LocalDateTime.of(2000, 1, 1, 23, 59, 59, 999);
localDateTime2 = LocalDateTime.of(2000, 1, 1, 00, 00, 00, 000);
assertThat(localDateTime1).isEqualToIgnoringHours(localDateTime2);
ZonedDateTime examples :
ZonedDateTime firstOfJanuary2000InUTC = ZonedDateTime.parse("2000-01-01T00:00:00Z");
assertThat(firstOfJanuary2000InUTC).isEqualTo(ZonedDateTime.parse("2000-01-01T00:00:00Z"));
// same assertion but AssertJ takes care of expected String to ZonedDateTime conversion
assertThat(firstOfJanuary2000InUTC).isEqualTo("2000-01-01T00:00:00Z");
// example showing that ZonedDateTime are compared in actual's time zone
assertThat(firstOfJanuary2000InUTC).isEqualTo("2000-01-01T01:00:00+01:00");
assertThat(firstOfJanuary2000InUTC).isAfter("1999-12-31T23:59:59Z");
assertThat(firstOfJanuary2000InUTC).isAfter("2000-01-01T00:30:00+01:00"); // 1999-12-31T23:30:00Z
assertThat(firstOfJanuary2000InUTC).isAfterOrEqualTo("1999-12-31T23:59:59Z")
.isAfterOrEqualTo("2000-01-01T00:00:00Z");
assertThat(firstOfJanuary2000InUTC).isBefore("2000-01-01T00:00:01Z")
.isBeforeOrEqualTo("2000-01-01T00:00:01Z")
.isBeforeOrEqualTo("2000-01-01T00:00:00Z");
// comparison with specific precision
ZonedDateTime zonedDateTime1 = ZonedDateTime.of(2000, 1, 1, 0, 0, 0, 0, ZoneOffset.UTC);
ZonedDateTime zonedDateTime2 = ZonedDateTime.of(2000, 1, 1, 23, 59, 59, 999, ZoneOffset.UTC);
ZonedDateTime zonedDateTime3 = ZonedDateTime.of(2000, 1, 1, 0, 59, 59, 999, ZoneOffset.UTC);
ZonedDateTime zonedDateTime4 = ZonedDateTime.of(2000, 1, 1, 0, 0, 59, 999, ZoneOffset.UTC);
ZonedDateTime zonedDateTime5 = ZonedDateTime.of(2000, 1, 1, 0, 0, 0, 999, ZoneOffset.UTC);
assertThat(zonedDateTime1).isEqualToIgnoringHours(zonedDateTime2);
assertThat(zonedDateTime1).isEqualToIgnoringMinutes(zonedDateTime3);
assertThat(zonedDateTime1).isEqualToIgnoringSeconds(zonedDateTime4);
assertThat(zonedDateTime1).isEqualToIgnoringNanos(zonedDateTime5);
Use assertThatThrownBy(ThrowingCallable) to capture and then assert on a Throwable, ThrowingCallable being a functinonal interface it can be expressed by a lambda.
Example :
@Test
public void testException() {
assertThatThrownBy(() -> { throw new Exception("boom!"); }).isInstanceOf(Exception.class)
.hasMessageContaining("boom");
}
BDD aficionados can separate when and then steps by using catchThrowable(ThrowingCallable) to capture the throwable and then perform assertions.
Example :
@Test
public void testException() {
// given some preconditions
// when
Throwable thrown = catchThrowable(() -> { throw new Exception("boom!") };);
// then
assertThat(thrown).isInstanceOf(Exception.class)
.hasMessageContaining("boom");
}
Assertions for Optional have been added.
Examples :
// optional with value
Optional<String> optional = Optional.of("Test");
assertThat(optional).isPresent()
.contains("Test");
// empty optional
Optional<Object> emptyOptional = Optional.empty();
assertThat(emptyOptional).isEmpty();
matches assertion will succeed if the given Predicate passes. It is available for all objects.
Example :
TolkienCharacter frodo = new TolkienCharacter("Frodo", 33, HOBBIT);
// actual refers to frodo
assertThat(frodo).matches(actual -> actual.age > 30 && actual.getRace() == HOBBIT);
It was already possible to compare float, double and BigDecimal with a margin error, it's now possible to do the same thing with int, long, short and byte.
Examples :
// import static org.assertj.core.api.Assertions.within;
assertThat(30).isCloseTo(40, within(10));
assertThat(10l).isCloseTo(8l, within(2l));
assertThat((short)5).isCloseTo((short)7, within((short)3));
assertThat((byte)5).isCloseTo((byte)7, within((byte)3));
It is now easier to build a Condition, one just has to provide a predicate and a description (instead of having to extends Condition). You can specify the description using String.format syntax.
Example :
// build a Condition with a Predicate
Condition<String> fairyTale = new Condition<String>(s -> s.startsWith("Once upon a time"),
"a %s tale", "fairy");
String littleRedCap = "Once upon a time there was a dear little girl ...";
assertThat(littleRedCap).is(fairyTale);
Release date : 2015-03-07
This is a major release, the first that relies on Java 7.
Thanks to Brice Dutheil, Tobias Bieniek, Alexandre Balhier, Francis Galiegue, Lukasz Kryger, Tim Perry, Jean-Christophe Gay, Lovro Pandzic and Alexander Bischof for their contributions.
Assertions for Path, it provides the assertions that were defined for File and add some new ones specific to Path.
Note that some assertions have two versions: a normal one and a "raw" one (for instance, hasParent() and hasParentRaw()). The difference is that normal assertions will canonicalize or normalize the tested path and, where applicable, the path argument, before performing the actual test. Canonicalization includes normalization.
Canonicalization may lead to an I/O error if a path does not exist, in which case the given assertions will fail with a PathsException. Also note that symbolic links will be followed if the filesystem supports them. Finally, if a path is not absolute, canonicalization will resolve the path against the process' current working directory.
Examples :
@Test
public void path_assertions() throws Exception {
// Create a regular file, and a symbolic link pointing to it
Path existingFile = Paths.get("somefile.txt");
write(existingFile, "foo".getBytes());
Path symlinkToExistingFile = Paths.get("symlink-to-somefile.txt");
deleteIfExists(symlinkToExistingFile);
createSymbolicLink(symlinkToExistingFile, existingFile);
// Create a symbolic link whose target does not exist
Path nonExistentPath = Paths.get("nonexistent");
Path symlinkToNonExistentPath = Paths.get("symlinkToNonExistentPath");
deleteIfExists(symlinkToNonExistentPath);
createSymbolicLink(symlinkToNonExistentPath, nonExistentPath);
// create directory and symlink to it
Path dir = Paths.get("target/dir");
deleteIfExists(dir);
createDirectory(dir);
Path dirSymlink = Paths.get("target", "dirSymlink");
deleteIfExists(dirSymlink);
createSymbolicLink(dirSymlink, dir.toAbsolutePath());
// assertions examples
assertThat(existingFile).exists();
assertThat(symlinkToExistingFile).exists();
assertThat(existingFile).existsNoFollowLinks();
assertThat(symlinkToNonExistentPath).existsNoFollowLinks();
assertThat(nonExistentPath).doesNotExist();
assertThat(existingFile).isRegularFile();
assertThat(symlinkToExistingFile).isRegularFile();
assertThat(symlinkToExistingFile).isSymbolicLink();
assertThat(dirSymlink).isDirectory().isSymbolicLink();
assertThat(symlinkToNonExistentPath).isSymbolicLink();
assertThat(dir).isDirectory();
assertThat(dirSymlink).isDirectory();
assertThat(dir).hasParent(Paths.get("target"))
.hasParent(Paths.get("target/dir/..")) // would fail with hasParentRaw
.hasParentRaw(Paths.get("target"));
assertThat(existingFile.toRealPath()).isCanonical();
assertThat(existingFile).hasFileName("somefile.txt");
assertThat(symlinkToExistingFile).hasFileName("symlink-to-somefile.txt");
// Unix specific assertions
assertThat(Paths.get("/foo/bar")).isAbsolute();
assertThat(Paths.get("foo/bar")).isRelative();
assertThat(Paths.get("/usr/lib")).isNormalized();
assertThat(Paths.get("a/b/c")).isNormalized();
assertThat(Paths.get("../d")).isNormalized();
assertThat(Paths.get("/")).hasNoParent();
assertThat(Paths.get("foo")).hasNoParentRaw();
assertThat(Paths.get("/usr/lib")).startsWith(Paths.get("/usr"))
.startsWith(Paths.get("/usr/lib/..")) // would fail with startsWithRaw
.startsWithRaw(Paths.get("/usr"));
assertThat(Paths.get("/usr/lib")).endsWith(Paths.get("lib"))
.endsWith(Paths.get("lib/../lib")) // would fail with endsWithRaw
.endsWithRaw(Paths.get("lib"));
}
Use assertThatThrownBy(ThrowingCallable) to capture and then assert on a Throwable.
Java 7 example :
assertThatThrownBy(new ThrowingCallable()
@Override
public void call() throws Exception {
throw new Exception("boom!");
}
}).isInstanceOf(Exception.class)
.hasMessageContaining("boom");
Java 8 example :
@Test
public void testException() {
assertThatThrownBy(() -> { throw new Exception("boom!"); }).isInstanceOf(Exception.class)
.hasMessageContaining("boom");
}
BDD aficionados can separate when and then steps by using catchThrowable(ThrowingCallable) to capture the throwable and then perform assertions.
Java 7 example :
@Test
public void testException() {
// when
Throwable thrown = catchThrowable(new ThrowingCallable()
@Override
public void call() throws Exception {
throw new Exception("boom!");
}
});
// then
assertThat(thrown).isInstanceOf(Exception.class)
.hasMessageContaining("boom");
}
Java 8 example :
@Test
public void testException() {
// when
Throwable thrown = catchThrowable(() -> { throw new Exception("boom!"); });
// then
assertThat(thrown).isInstanceOf(Exception.class)
.hasMessageContaining("boom");
}
To avoid having to call assertAll() at the end of your test methods, use AutoCloseableSoftAssertions with try-with-resources statement :
@Test
public void host_dinner_party_where_nobody_dies() {
Mansion mansion = new Mansion();
mansion.hostPotentiallyMurderousDinnerParty();
try (AutoCloseableSoftAssertions softly = new AutoCloseableSoftAssertions()) {
// use SoftAssertions instead of direct assertThat methods
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 when softly is closed.
}
}
Verifies that two Date/Timestamp correspond to the same time.
Example:
@Test
public void verify_that_date_and_timestamp_correspond_to_the_same_time() {
Date date = new Date();
Timestamp timestamp = new java.sql.Timestamp(date.getTime());
assertThat(date).hasSameTimeAs(timestamp);
assertThat(timestamp).hasSameTimeAs(date);
}
This assertion verifies that the actual map contains the given values.
Example:
Map<Ring, TolkienCharacter> ringBearers = ... // init with elves rings and the one ring
assertThat(ringBearers).containsValues(frodo, galadriel);
This assertion verifies that the actual map does not contain the given keys.
Example:
Map<Ring, TolkienCharacter> ringBearers = ... // init with elves rings only
assertThat(ringBearers).doesNotContainKeys(oneRing, someManRing);
This is useful when the object under test is a List but was declared as Object, in that case you can only have Object assertions, using asList() you will be able to use List assertions.
Example:
Object listAsObject = Arrays.asList(1, 2, 3);
// DOES NOT COMPILE as isSorted() is not an Object assertions
assertThat(listAsObject).isSorted();
// works as we have switched to List assertions
assertThat(listAsObject).asList().isSorted();
This is useful when the object under test is a String but was declared as Object, in that case you can only have Object assertions, using asString() you will be able to use String assertions.
Example:
Object stringAsObject = "hello world";
// DOES NOT COMPILE as contains() is not an Object assertions
assertThat(stringAsObject).contains("hello");
// works as we have switched to String assertions
assertThat(stringAsObject).asString().contains("hello");
Extracting is now able to extract values corresponding to the given keys.
Example:
Employee yoda = new Employee(1L, new Name("Yoda"), 800);
Employee luke = new Employee(2L, new Name("Luke"), 22);
Employee han = new Employee(3L, new Name("Han"), 31);
// build two maps
Map<String, Employee> map1 = new HashMap<>();
map1.put("key1", yoda);
map1.put("key2", luke);
Map<String, Employee> map2 = new HashMap<>();
map2.put("key1", yoda);
map2.put("key2", han);
// instead of a list of objects, we have a list of maps
List<Map<String, Employee>> maps = asList(map1, map2);
// extracting a property in that case = get values from maps using property as a key
assertThat(maps).extracting("key2").containsExactly(luke, han);
assertThat(maps).extracting("key1").containsExactly(yoda, yoda);
// it works with several keys, extracted values being wrapped in a Tuple
assertThat(maps).extracting("key1", "key2").containsExactly(tuple(yoda, luke), tuple(yoda, han));
// unknown keys leads to null (map behavior)
assertThat(maps).extracting("bad key").containsExactly(null, null);
BDD soft assertions are like sot assertions but use then() instead of assertThat() to start assertions.
Note that JUnitBDDSoftAssertions and AutoCloseableSoftAssertions are also available, assertAll() being automatically called respectively by a JUnit rule or the implicit close method in a try-with-resources statement.
Example:
@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");
// use JUnitBDDSoftAssertions or AutoCloseableSoftAssertions to avoid having to call assertAll()
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]'>
If you call withThreadDumpOnError()before your assertions and an assertion error occurs, the thread dump will be printed on System.err.
Example:
assertThat("Messi").withThreadDumpOnError().isEqualTo("Ronaldo");
will print the thread dump, something looking like:
"JDWP Command Reader"
java.lang.Thread.State: RUNNABLE
"JDWP Event Helper Thread"
java.lang.Thread.State: RUNNABLE
"JDWP Transport Listener: dt_socket"
java.lang.Thread.State: RUNNABLE
"Signal Dispatcher"
java.lang.Thread.State: RUNNABLE
"Finalizer"
java.lang.Thread.State: WAITING
at java.lang.Object.wait(Native Method)
at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:135)
at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:151)
at java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:189)
"Reference Handler"
java.lang.Thread.State: WAITING
at java.lang.Object.wait(Native Method)
at java.lang.Object.wait(Object.java:503)
at java.lang.ref.Reference$ReferenceHandler.run(Reference.java:133)
"main"
java.lang.Thread.State: RUNNABLE
at sun.management.ThreadImpl.dumpThreads0(Native Method)
at sun.management.ThreadImpl.dumpAllThreads(ThreadImpl.java:446)
at org.assertj.core.internal.Failures.threadDumpDescription(Failures.java:193)
at org.assertj.core.internal.Failures.printThreadDumpIfNeeded(Failures.java:141)
at org.assertj.core.internal.Failures.failure(Failures.java:91)
at org.assertj.core.internal.Objects.assertEqual(Objects.java:314)
at org.assertj.core.api.AbstractAssert.isEqualTo(AbstractAssert.java:198)
at org.assertj.examples.ThreadDumpOnErrorExample.main(ThreadDumpOnErrorExample.java:28)
Verifies that the actual Throwable has a cause similar to the given one, that is with same type and message (it does not use equals method for comparison).
Example:
Throwable invalidArgException = new IllegalArgumentException("invalid arg");
Throwable throwable = new Throwable(invalidArgException);
// This assertion succeeds:
assertThat(throwable).hasCause(invalidArgException);
// These assertions fail:
assertThat(throwable).hasCause(new IllegalArgumentException("bad arg"));
assertThat(throwable).hasCause(new NullPointerException());
assertThat(throwable).hasCause(null); // prefer hasNoCause()
Release date : 2015-01-02
This is a minor release to support assertions for Iterable using bounded wildcard thanks to Johannes Schneider.
Example :
// note we use a bounded wildcard list
List<? extends BasketBallPlayer> bulls = newArrayList(rose, noah);
// did not compile in 1.7.0 but works in 1.7.1+
assertThat(bulls).contains(rose, noah);
Release date : 2014-10-04
Thanks to Mateusz Haligowski, Chris Arnott, Andrew Gaul, dmwvr, Alexandre Balhier, Adam Ruka, Mariusz Smykula and Marcin Mikosik for their contributions.
An unexpected breaking change has been discovered after 1.7.1 release, Comparable assertions prevent access to Object assertions like isEqualToComparingFieldByField, this issue will be fixed in 2.0.
Thanks to Mateusz Haligowski, you can now use a type safe extracting feature, you only have to implement the Extractor interface to define what you are extracting.
Example:
// extract 'age' field values
assertThat(fellowshipOfTheRing).extracting(age()).contains(33, 38, 36);
// extracting works also with user's types (here Race)
assertThat(fellowshipOfTheRing).extracting(race()).contains(HOBBIT, ELF)
.doesNotContain(ORC);
// extract 'name' and 'age' values.
assertThat(fellowshipOfTheRing).extracting(ageAndRace()).contains(tuple(33, HOBBIT),
tuple(38, HOBBIT),
tuple(1000, ELF));
Here's what ageAndRace() extractor looks like:
public class TolkienCharacterAgeAndRaceExtractor implements Extractor<TolkienCharacter, Tuple> {
@Override
public Tuple extract(TolkienCharacter input) {
return new Tuple(input.age, input.getRace());
}
public static Extractor<TolkienCharacter, Tuple> ageAndRace() {
return new TolkienCharacterAgeAndRaceExtractor();
}
}
We can do more than extracting values, we can also flatten them, much like a functional flatMap:
Example:
// BasketBallPlayer.getTeamMates returns a List<BasketBallPlayer>
BasketBallPlayer noah = ... // initialized with Derrick Rose and Pau Gasol as teamates
BasketBallPlayer james = ... // initialized with Kevin Love and Kyrie Irving as teamates
// extract team mates and "flatten" them to a single BasketBallPlayer collection
assertThat(asList(noah, james)).flatExtracting(teammates()).contains(gasol, love, irving, rose);
// teammates() extractor
public class BasketBallTeammatesExtractor
implements Extractor<BasketBallPlayer, List<BasketBallPlayer>> {
@Override
public List<BasketBallPlayer> extract(BasketBallPlayer player) {
return player.getTeamMates();
}
public static Extractor<BasketBallPlayer, List<BasketBallPlayer>> teammates() {
return new BasketBallTeammatesExtractor();
}
}
Mateusz has published a nice article on this new feature.
This assertion verifies that the actual map contains only the given keys and nothing else, in any order.
Example:
Map<Ring, TolkienCharacter> ringBearers = ... // init with elves rings and the one ring
// assertion will pass
assertThat(ringBearers).containsOnlyKeys(nenya, narya, vilya, oneRing);
// assertion will fail because of two missing keys and an unexpected one (dwarfRing)
assertThat(ringBearers).containsOnlyKeys(oneRing, nenya, dwarfRing);
Thanks to Chris Arnott for this contribution.
This assertion verifies that the actual map has the same size as the given Map.
Example:
Map<Ring, TolkienCharacter> ringBearers = ... // init with elves rings and the one ring
// assertion will pass
assertThat(ringBearers).hasSameSizeAs(mapOf(entry(oneRing, frodo),
entry(narya, gandalf),
entry(nenya, galadriel),
entry(vilya, elrond)));
Thanks to Adam Ruka for this contribution.
The shell script will convert mots of your TestNG assertions to AssertJ ones.
Usage:
# default to *Test.java if you don't provide a pattern
./convert-testng-assertions-to-assertj.sh "*IT.java"
Thanks to Alexandre Balhier for this contribution.
This assertion verifies that the actual String/CharSequence has the expected number of lines.
Example:
String multiLine = "First line\n" +
"Last line";
assertThat(multiLine).hasLineCount(2);
Thanks to Mariusz Smykula for this contribution.
This assertion verifies that the actual iterable contains only the elements of the given iterable and nothing else, in any order.
Example:
Iterable<Ring> rings = newArrayList(nenya, vilya);
// assertion will pass
assertThat(rings).containsOnlyElementsOf(newLinkedList(nenya, vilya));
assertThat(rings).containsOnlyElementsOf(newLinkedList(nenya, nenya, vilya, vilya));
// assertion will fail as actual does not contain narya.
assertThat(rings).containsOnlyElementsOf(newLinkedList(nenya, vilya, narya));
// assertion will fail as actual contain nenya.
assertThat(rings).containsOnlyElementsOf(newLinkedList(vilya));
Thanks to Chris Arnott for this contribution.
This assertion verifies that the actual iterable contains only the elements of the given iterable and nothing else, in any order.
Example:
Iterable<Ring> elvesRings = newArrayList(vilya, nenya, narya);
// assertions will pass
assertThat(elvesRings).hasSameElementsAs(newArrayList(nenya, narya, vilya));
assertThat(elvesRings).hasSameElementsAs(newArrayList(nenya, narya, vilya, nenya));
// assertions will fail
assertThat(elvesRings).hasSameElementsAs(newArrayList(nenya, narya));
assertThat(elvesRings).hasSameElementsAs(newArrayList(nenya, narya, vilya, oneRing));
This assertion verifies that there is at least one element in the actual iterable or array satisfying the given condition.
Example:
List<BasketBallPlayer> bullsPlayers = newArrayList(noah, rose);
// potentialMvp is a Condition<BasketBallPlayer>
assertThat(bullsPlayers).haveAtLeastOne(potentialMvp);
Thanks to Adam Ruka for this contribution.
These assertions verifies the type of the Iterable/Array elements.
Example:
// hasOnlyElementsOfType check
List<Long> numbers = newArrayList(1L, 2L);
assertThat(numbers).hasOnlyElementsOfType(Number.class)
.hasOnlyElementsOfType(Long.class);
// hasAtLeastOneElementOfType check
assertThat(newArrayList("string", 1L)).hasAtLeastOneElementOfType(String.class);
AssertJ now provides basic assertions for Comparable types.
Example:
Rating goodRating = new Rating(8);
Rating badRating = new Rating(4);
// basic assertions available for all Comparable types.
assertThat(goodRating).isGreaterThan(badRating);
assertThat(goodRating).isGreaterThanOrEqualTo(badRating);
assertThat(badRating).isLessThan(goodRating);
assertThat(badRating).isLessThanOrEqualTo(goodRating);
public class Rating implements Comparable {
private int note;
public Rating(int note) {
this.note = note;
}
@Override
public int compareTo(Rating r) {
return this.note - r.note;
}
}
Thanks to dmwvr for this contribution.
You can use field by field element comparison for array/iterable assertions but before 1.7.0 it only worked for array/iterable specific assertions and not basic ones isEqualTo(), now the semantics are also applied for basic assertions.
Example:
TolkienCharacter frodo = new TolkienCharacter("Frodo", 33, HOBBIT);
TolkienCharacter sam = new TolkienCharacter("Sam", 38, HOBBIT);
// frodo and sam both are hobbits -> they are equal when comparing only race (worked before 1.7.0)
assertThat(newArrayList(frodo)).usingElementComparatorOnFields("race").contains(sam);
// Before 1.7.0, this basic assertion would not work as element comparison semantics
// were only honoured in IterableAssert/Array specific assertions, but now it works !
assertThat(newArrayList(frodo)).usingElementComparatorOnFields("race").isEqualTo(newArrayList(sam));
Release date : 2014-06-01
This is a minor release to fix an OSGI incompatibility discovered by Giuseppe Guarnieri (thanks !), we also expose List<String> linesOf(File file) directly in the Assertions entry point class.
Release date : 2014-03-15
Thanks to Mariusz Smykula, Michal Lipski, Kamil Szymanski, Fabien Meurisse, Adam Dąbrowski, Paweł Barszcz, Clément Cunin, Gregor Zeitlinger, William Delanoue, Jean Christophe Gay, Tomasz Bartczak, Michal Bareja and Michał Piotrkowski for their contributions.
Example:
File xFileWithExtension = writeFile("xFile.secret", "The Truth Is Out There");
assertThat(xFileWithExtension).hasParent("target")
.hasParent(new File("target"))
.hasExtension("secret")
.hasName("xFile.secret");
assertThat(new File("/")).hasNoParent();
Thanks to Jean Christophe Gay for this contribution.
AssertJ allows now to register several custom date formats and their use is thread safe.
Example :
// You can use date String representation with various default format:
// - yyyy-MM-dd
// - yyyy-MM-dd'T'HH:mm:ss,
// - yyyy-MM-dd'T'HH:mm:ss.SSS,
assertThat(theTwoTowers.getReleaseDate()).isEqualTo("2002-12-18");
assertThat(theTwoTowers.getReleaseDate()).isEqualTo("2002-12-18T00.00.00");
// But you can register on or several custom date format (this is thread safe):
Assertions.registerCustomDateFormat("dd/MM/yyyy");
assertThat(theTwoTowers.getReleaseDate()).isEqualTo("18/12/2002");
// default date formats can still be used
assertThat(theTwoTowers.getReleaseDate()).isEqualTo("2002-12-18");
Example:
// within : static import of org.assertj.core.api.Assertions.within
assertThat(8.1).isCloseTo(8.0, within(0.1));
Extracting feature is now able to read private fields, for example:
// trilogy is collection of Movie which has a duration private field.
assertThat(trilogy).extracting("duration").containsExactly("178 min", "179 min", "201 min");
// you can disable private field extraction
setAllowExtractingPrivateFields(false);
// now assertion fails with an IntrospectionError.
assertThat(trilogy).extracting("duration").containsExactly("178 min", "179 min", "201 min");
Thanks to Michal Bareja and Paweł Barszcz for this contribution.
Sometimes it is difficult to find differences from standard message, for example:
assertThat("µµµ").contains("μμμ");
But with hexadecimal representation the difference is clear:
assertThat("µµµ").inHexadecimal().contains("μμμ");
Error:
Expecting:
<"['0x00B5', '0x00B5', '0x00B5']">
to contain:
<"['0x03BC', '0x03BC', '0x03BC']">
Thanks to Mariusz Smykula for this huge contribution.
When using Iterable assertions, you can now compare expected elements with actual ones using field by field comparison instead of equals method.
Example:
TolkienCharacter frodo = new TolkienCharacter("Frodo", 33, HOBBIT);
TolkienCharacter sam = new TolkienCharacter("Sam", 38, HOBBIT);
// frodo and sam both are hobbits, so they are equal when comparing only race
assertThat(newArrayList(frodo)).usingElementComparatorOnFields("race").contains(sam); // OK
// ... but not when comparing both name and race
assertThat(newArrayList(frodo)).usingElementComparatorOnFields("name", "race").contains(sam); // FAIL
Thanks to Tomasz Bartczak and Adam Dąbrowski for this contribution.
In case of error the actual field values are displayed (before only the expected values were), example:
This assertion ...
assertThat(frodo).isEqualToComparingOnlyGivenFields(sam, "name", "race", "age");
... will fail with the following error:
Expecting values:
<["Sam", 38]>
in fields:
<["name", "age"]>
but were:
<["Frodo", 33]>
in <Frodo 33 years old Hobbit>.
Comparison was performed on fields:
<["name", "race", "age"]>
Thanks to Michal Lipski and Paweł Barszcz for this contribution.
Instead of using assertThat use then to start assertions, example:
@Test
public void host_dinner_party_where_nobody_dies() {
//given
Mansion mansion = new Mansion();
//when
mansion.hostPotentiallyMurderousDinnerParty();
then(mansion.guests()).isEqualTo(6);
then(mansion.kitchen()).isEqualTo("clean");
then(mansion.library()).isEqualTo("messy");
then(mansion.revolverAmmo()).isEqualTo(6);
then(mansion.candlestick()).isEqualTo("bent");
then(mansion.colonel()).isEqualTo("well kempt");
then(mansion.professor()).isEqualTo("bloodied and disheveled");
}
Thanks to Mariusz Smykula for this contribution.
To avoid having to call assertAll() at the end of your test methods, let JUnitSoftAssertions JUnit rule triggers automatically the assertions global verification :
@Rule
public JUnitSoftAssertions softly = new JUnitSoftAssertions();
@Test
public void host_dinner_party_where_nobody_dies() {
Mansion mansion = new Mansion();
mansion.hostPotentiallyMurderousDinnerParty();
// use SoftAssertions instead of direct assertThat methods
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 call to softly.assertAll(), assertions global verification is done by JUnitSoftAssertions rule
}
This works only for JUnit, in TestNG however it does not seem possible to make the global verification in an @AfterMethod method because if it throws an exception, TestNG skips all subsequent tests.
Thanks to Gregor Zeitlinger for this contribution.
Release date : 2013-11-06
Thanks to William Delanoue, Jean Christophe Gay, Tomasz Bartczak and Michał Piotrkowski for their contributions.
Like extracting feature but instead of extracting properties/fields, it extracts the result of given method invocation on the elements of Iterable/Array under test and puts the results into a new Iterable/Array which becomes the object under test.
It allows you to test the results of method call on elements instead of testing the elements themselves, it's especially useful for classes that does not conform to Java Bean's getter specification (e.g toString() or String status() instead of String getStatus()).
Let's take an example to make things clearer :
// Build a array of WesterosHouse, a WesterosHouse has a method: public String sayTheWords()
List<WesterosHouse> greatHouses = new ArrayList<WesterosHouse>();
greatHouses.add(new WesterosHouse("Stark", "Winter is Coming"));
greatHouses.add(new WesterosHouse("Lannister", "Hear Me Roar!"));
greatHouses.add(new WesterosHouse("Greyjoy", "We Do Not Sow"));
greatHouses.add(new WesterosHouse("Baratheon", "Our is the Fury"));
greatHouses.add(new WesterosHouse("Martell", "Unbowed, Unbent, Unbroken"));
greatHouses.add(new WesterosHouse("Tyrell", "Growing Strong"));
// let's verify the words of great houses in Westeros:
assertThat(greatHouses).extractingResultOf("sayTheWords")
.contains("Winter is Comming", "We Do Not Sow", "Hear Me Roar")
.doesNotContain("Lannisters always pay their debts");
Thanks to Michał Piotrkowski for this contribution.
isEqualToIgnoring<Millis/Seconds/Minutes/Hours> assertions allow you to compare two dates ignoring time fields below given precision, for example if you ignore minutes then seconds and milliseconds will be ignored too.
Code example: compare two dates without minutes, seconds and milliseconds
Date date1 = parseDatetime("2003-04-26T13:01:35");
Date date2 = parseDatetime("2003-04-26T13:02:00");
// OK : all dates fields are the same if we leave minutes seconds and milliseconds fields
assertThat(date1).isEqualToIgnoringMinutes(date2);
// KO : fail as minute fields differ
assertThat(date1).isEqualToIgnoringSeconds(date2);
Thanks to William Delanoue for this contribution.
With isInSame<Second/Minute/Hour>WindowAs> you can check that two dates are in the same time window with a true chronological comparison and not a field by field comparison like we do in isInSame<Second/Minute/Hour>As.
Let's see that on an example :
Date date1 = parseDatetimeWithMs("2003-04-26T13:01:02.999");
Date date2 = parseDatetimeWithMs("2003-04-26T13:01:03.000");
// OK : assertion succeeds as time difference is 1ms < 1s
assertThat(date1).isInSameSecondWindowAs(date2);
// KO : isInSameSecondAs assertion fails as seconds fields differ.
assertThat(date1).isInSameSecondAs(date2);
You can use date String representation with various format, AssertJ takes care of parsing String as Date:
// - yyyy-MM-dd
assertThat(theTwoTowers.getReleaseDate()).isEqualTo("2002-12-18");
// - yyyy-MM-dd'T'HH:mm:ss
assertThat(theTwoTowers.getReleaseDate()).isEqualTo("2002-12-18T00.00.00");
// - yyyy-MM-dd'T'HH:mm:ss.SSS
assertThat(theTwoTowers.getReleaseDate()).isEqualTo("2002-12-18T00.00.00.000");
Add containsOnly and containsExactly to Map assertions using the same semantics as the one in Iterable assertions:
import static org.assertj.core.api.Assertions.entry;
Map<String, TolkienCharacter> characters = new LinkedHashMap<String, TolkienCharacter>();
characters.put(frodo.getName(), frodo);
characters.put(galadriel.getName(), galadriel);
characters.put(gandalf.getName(), gandalf);
characters.put(sam.getName(), sam);
assertThat(characters).containsOnly(entry(sam.getName(), sam),
entry(frodo.getName(), frodo),
entry(gandalf.getName(), gandalf),
entry(galadriel.getName(), galadriel));
assertThat(characters).containsExactly(entry(frodo.getName(), frodo),
entry(galadriel.getName(), galadriel),
entry(gandalf.getName(), gandalf),
entry(sam.getName(), sam));
Release date : 2013-11-06
Thanks to Brian Laframboise, William Delanoue, Marcus Klimstra, Ted Young, Piotr Betkier, Marcin Mikosik and Jean Christophe Gay for their contributions.
String based XML assertions have been added, it allows you to compare a String representing an XML document with another one whatever how formatted the XML is. Let's see that with some examples :
String expectedXml = "<rings>\n" +
" <bearer>\n" +
" <name>Frodo</name>\n" +
" <ring>\n" +
" <name>one ring</name>\n" +
" <createdBy>Sauron</createdBy>\n" +
" </ring>\n" +
" </bearer>\n" +
"</rings>";
// XML String don't need to be formatted, isXmlEqualTo is able to compare it with another xml String.
String oneLineXml = "<rings><bearer><name>Frodo</name>"
+ "<ring><name>one ring</name><createdBy>Sauron</createdBy>"
+ "</ring></bearer></rings>";
assertThat(oneLineXml).isXmlEqualTo(expectedXml);
Since AssertJ formats both actual and expected XML String the same way, it's easy to see what was different in case of error.
You can also easily compare your XML String to the content of an XML file, e.g:
assertThat(xmlString).isXmlEqualToContentOf(new File("expected.xml"));
Using soft assertions, AssertJ collects all assertion errors instead of stopping at the first one.
So, assuming something goes awry at your dinner party, when using "standard" assertions, this test ...
@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");
}
... will yield the less-than-ideal exception message :
org.junit.ComparisonFailure: [Living Guests] expected:<[7]> but was<[6]>
Using soft assertions you can collect all the failed assertions together like so:
@Test
public void host_dinner_party_where_nobody_dies() {
Mansion mansion = new Mansion();
mansion.hostPotentiallyMurderousDinnerParty();
// use SoftAssertions instead of direct assertThat methods
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");
// Don't forget to call SoftAssertions global verification !
softly.assertAll();
}
When the collected assertions are all asserted together they yield a more descriptive error message:
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 dishevelled]'>
Thanks to Brian Laframboise for this contribution.
Release date : 2013-06-30
Thanks to William Delanoue, Jean Christophe Gay, Ted M. Young and Mikhail Mazursky for their contributions.
The following assertions that were deprecated since the first version (and coming from Fest Assert) have been removed, we thought that they were very unclear:
Class assertions have been added, let's see that with some examples:
assertThat(Magical.class).isAnnotation();
assertThat(Ring.class).isNotAnnotation()
.hasAnnotation(Magical.class);
assertThat(TolkienCharacter.class).isNotInterface();
assertThat(Person.class).isAssignableFrom(Employee.class);
// You can check Class fields with :
// - hasFields for public fields
assertThat(TolkienCharacter.class).hasFields("age");
// - hasDeclaredFields for all declared fields (whatever field's visibility)
assertThat(TolkienCharacter.class).hasDeclaredFields("name", "race");
Release date : 2013-05-12
Thanks to William Delanoue and Mikhail Mazursky for their contributions.
The First improvement is related to map entries, often testing map entries looks like :
Map<String, String> address = ....
assertThat(address).includes(MapAssert.entry("zip", "43865"),
MapAssert.entry("lastName", "Frazier"),
MapAssert.entry("state", "IA"),
MapAssert.entry("city", "Culloden"));
We can simplify this by getting rid of the repeated MapAssert.entry calls:
assertThat(address).containsEntry("zip", "43865")
.containsEntry("lastName", "Frazier")
.containsEntry("state", "IA")
.containsEntry("city", "Culloden");
Same thing has been done with doesNotContainEntry.
The second improvement is to allow checking that a Map contains multiple keys at once, so instead of :
assertThat(elvesRingBearers).containsKey(nenya).containsKey(narya).containsKey(vilya);
you can now write :
assertThat(elvesRingBearers).containsKeys(nenya, narya, vilya);
Make isEqualTo, isSameAs and isNotSameAs assertions more flexible by not using generics in "expected" parameter.
It solves the following problem where an Employee class inherits from Person :
Employee bill = new Employee("Bill", 50, "micro$oft");
// OK
assertThat(bill).isEqualTo(bill);
// now let's view billou as a Person and not an Employee anymore
Person billou = bill;
// Before 1.2.0 version, the next line used led to a compile error as
// parameter expected type is Employee (although bill and billou are identical).
assertThat(bill).isEqualTo(billou);
The only drawback is less strong type checking but we think flexibility is more important that type checks.
Note that this is the beginning of making AssertJ more flexible, there is still work to be done in this area.
Release date : 2013-04-15
With extracting you can extract values from an array/iterable elements and perform assertions on those extracted values.
It is similar to extractProperty feature but is easier to use (I think), it is also able to extract properties as well as public fields while extractProperty can only extract properties (as its name suggests).
Last but not least, you can extract several public fields and properties at once, the extracted values corresponding to the same element being grouped in a tuple.
Simple example showing how to check the names of TolkienCharacter elements in fellowshipOfTheRing list :
// "name" need to be either a property or a public field of TolkienCharacter class.
assertThat(fellowshipOfTheRing).extracting("name")
.contains("Boromir", "Gandalf", "Frodo", "Legolas")
.doesNotContain("Sauron", "Elrond");
Example showing how to check the name, age and race's name of each TolkienCharacter elements :
the extracted name, age and race's name values corresponding to the same element are grouped in a tuple, thus you need to use tuples for expected values.
// tuple comes from : import static org.assertj.core.api.Assertions.tuple;
assertThat(fellowshipOfTheRing).extracting("name", "age", "race.name")
.contains(tuple("Boromir", 37, "Man"),
tuple("Sam", 38, "Hobbit"),
tuple("Legolas", 1000, "Elf"));
This feature is a much more powerful version of onProperty that was introduced in Fest 1.4.
Error messages are now multiline to ease comparing the actual value to the expected one.
Here an example with a failing Date assertion :
// failing assertion !
assertThat(parse("2013-01-01")).isBefore(parse("2000-01-01"));
In assertj-core 1.0.0, it produces this error message :
expected:<2013-01-01T00:00:00> to be strictly before:<2000-01-01T00:00:00>
In assertj-core 1.1.0 the error message is now :
Expecting:
<2013-01-01T00:00:00>
to be strictly before:
<2000-01-01T00:00:00>
Note that involved objects are aligned to the same column to ease comparing them.
Release date : 2013-03-26
1.0.0 version is the first AssertJ release after the fork from FEST 2.0M10. These are the changes compared to FEST 2.0M10 :