Assertj like a pro

Abstract

  • API semantic
  • support other libraries
  • starts with assertThat

Collection

assertThat(List.of(1,2,3,4)).first().isEqualTo(1);
assertThat(List.of(1,2,3,4)).last().isEqualTo(1);
assertThat(List.of(1)).singleElement().isEqualTo(1);

Extracting

assertThat(person).extracting("address.postalCode.code").isEqualTo("45500");
assertThat(person).extracting(p -> p.address().postalCode().code()).isEqualTo("45500");
assertThat(person).extracting("address.postalCode.code").contains("45500", "75000");

SoftAssertions

var softly = new SoftAssertions();
softly.assertThat(collection).isNotEmpty();
softly.assertThat(string).contains("test");
softly.assertThat(number).isGreaterThan(42);
// don't forget to call assertAll
softly.assertAll();
 
// better
SoftAssertions.assertSoftly(softly -> {
  softly.assertThat(collection).isNotEmpty();
  softly.assertThat(string).contains("test");
  softly.assertThat(number).isGreaterThan(42);
});

Temporal assertions

assertThat(now).isAfter(start).isBefore(end).isBetween(start, end);
assertThat(now).isCloseTo(start, within(1, ChronoUnit.MINUTES));

Validators

assertThatThrownBy(() -> validator.validate(toValidate))
  .isInstanceOf(ValidationException.class)
  .extracting("errors", InstanceOfAssertFactories.collection(ErrorDetails.class))
  .hasSize(1)
  .first()
  .isEqualTo(new ErrorDetails("name", ErrorCode.SHOULD_NOT_BE_NULL));

Conditions

Condition&gt;Integer> isTheAnswer = new Condition<>(i => i == 42, "Your answeris wrong");
assertThat(answer).satisfies(isTheAnswer);
 
var hasSingleNotNullError = new Condition&gt;ValidationException>(
  v -> v.getErrors().size == 1
    && v.getErrors()
        .stream()
        .findFirst()
        .orElseThrow()
        .errorCode()
        .equals(ErrorCode.SHOULD_NOT_BE_NULL),
    "Has single error which is SHOULD_NOT_BE_NULL"
);
assertThatThrownBy(() -> validator.validate(toValidate))
  .asInstanceOf(InstanceOfAssertFactories.type(ValidationException.class))
  .satisfies(hasSingleNotNullError);

Custom assertion

public class ValidationExceptionAssert extends AbstractThrowableAssert<ValidationExceptionAssert, ValidationException> {
  // ...
 
  public ValidationExceptionAssert hasOnlyThisErrorDetails(String field, ErrorCode errorCode) {
    // ...
  }
 
  public static InstanceOfAssertFactory<...> factory() {
    return new InstanceOfAssertFactory<>(ValidationException.class, ValidationExceptionAssert::new);
  }
}
 
assertThatThrownBy(() -> validator.validate(toValidate))
  .asInstanceOf(ValidationExceptionAssert.factory())
  .hasOnlyThisErrorDetails("name", ErrorCode.SHOULD_NOT_BE_NULL);