Repository: assertj/assertj

Issue #2557: `assertThat(comparable)` returns `ObjectAssert` instead of `AbstractComparableAssert`
Created: 2022-04-03T13:24:30Z
Summary
Given a Comparable<T> variable, it's currently not possible to use assertions from ComparableAssert unless T is Object.
Also, if the type implementing Comparable targets a parent type that is not Object, assertThat always returns ObjectAssert for both strongly-typed and Comparable<T> variables.
Example: JDK type not comparing with Object
Comparable<String> comparable = "value";

assertThat(comparable)            // ObjectAssert<Comparable<String>>
  .isEqualByComparingTo("value"); // does not compile
Example: Custom type comparing with self
class ComparingWithSelf implements Comparable<ComparingWithSelf> {
  @Override
  public int compareTo(ComparingWithSelf other) {
    return 0;
  }
}

Comparable<ComparingWithSelf> comparable = new ComparingWithSelf();

assertThat(comparable)                            // ObjectAssert<Comparable<ComparingWithSelf>>
  .isEqualByComparingTo(new ComparingWithSelf()); // does not compile

ComparingWithSelf comparingWithSelf = new ComparingWithSelf();

assertThat(comparingWithSelf)                     // AbstractComparableAssert<?, ComparingWithSelf>
  .isEqualByComparingTo(new ComparingWithSelf()); // compiles
Example: Custom type comparing with parent
class Parent {}

class ComparingWithParent extends Parent implements Comparable<Parent> {
  @Override
  public int compareTo(Parent other) {
    return 0;
  }
}

Comparable<Parent> comparable = new ComparingWithParent();

assertThat(comparable)                              // ObjectAssert<Comparable<Parent>>
  .isEqualByComparingTo(new ComparingWithParent()); // does not compile

ComparingWithParent comparingWithParent = new ComparingWithParent();

assertThat(comparingWithParent)                     // ObjectAssert<ComparingWithParent>
  .isEqualByComparingTo(new ComparingWithParent()); // does not compile
Example: Custom type comparing with Object
class ComparingWithObject implements Comparable<Object> {
  @Override
  public int compareTo(Object other) {
    return 0;
  }
}

Comparable<Object> comparable = new ComparingWithObject();

assertThat(comparable)                              // AbstractComparableAssert<?, Comparable<Object>
  .isEqualByComparingTo(new ComparingWithObject()); // compiles

ComparingWithObject comparingWithObject = new ComparingWithObject();

assertThat(comparingWithObject)                     // AbstractComparableAssert<?, ComparingWithObject>
  .isEqualByComparingTo(new ComparingWithObject()); // compiles
Workaround: Raw type
Comparable comparable = "value";  // "rawtypes" warning

assertThat(comparable)            // AbstractComparableAssert<?, Comparable> with "unchecked" warning
  .isEqualByComparingTo("value"); // compiles with "unchecked" warning
Workaround: asInstanceOf
This works only with non-null instances due to the null-check performed in asInstanceOf.
Comparable<String> comparable = "value";

assertThat(comparable)                    // ObjectAssert<Comparable<String>>
  .asInstanceOf(comparable(String.class)) // AbstractComparableAssert<?, String>
  .isEqualByComparingTo("value");         // compiles
Current status



assertThat use case
Comparable<T> variable
Strongly-typed variable




JDK type not comparing with Object
ObjectAssert
N/A (dedicated assertions)


Custom type comparing with self
ObjectAssert
AbstractComparableAssert


Custom type comparing with parent
ObjectAssert
ObjectAssert


Custom type comparing with Object
AbstractComparableAssert
AbstractComparableAssert

Duplicate issue #3431: Comparable interfaces can't be checked with isGreater/isLess directly
Created: 2024-04-16T16:13:27Z
Feature summary
This doesn't compile.
Example
  @Test
  void gt() {
    Comparable<String> s1 = that -> 1;
    Comparable<String> s2 = that -> 0;
    assertThat(s1).isGreaterThan(s2);
  }

Closing comment (2024-04-17T06:40:57Z): You're hitting two problems here:

There is a known issue with generics (#2557) and you should use assertThatComparable if you must work with Comparable variables. We'll make it better in version 4.
isGreaterThan expects a concrete Comparable value, i.e., a String in your example, so the compilation error is the correct behavior.

Closing as duplicate of #2557.