3

The Javadoc gives this example for the matches method:

assertThat(player).matches(p -> p.isRookie());

And indeed, when I define a dummy class Player, the above statement compiles ok. However, when I define a class that derives from Exception, then the following doesn't compile:

public class MyCustomException extends Exception {
    public boolean isMyCustomFieldSet() { return true; }
}
...
MyCustomException myCustomException = new MyCustomExcpetion();
assertThat(myCustomException).matches(e -> e.isMyCustomFieldSet());

I can make it compile by using a cast:

assertThat(myCustomException).matches(e -> ((MyCustomException)e).isMyCustomFieldSet());

but that cast looks "ugly" and a bit of a hack to work around some sort of deficiency. Can I make it compile in a "nicer" way, i.e. without using a cast?

DodgyCodeException
  • 5,963
  • 3
  • 21
  • 42

3 Answers3

5

The issue is in Assertions, it declares AbstractThrowableAssert<?, ? extends Throwable> assertThat(Throwable t) instead of <T> AbstractThrowableAssert<?, T extends Throwable> assertThat(T t)

But unfortunately this can not be done because of the following existing method that clashes with it: public static <T> ObjectAssert<T> assertThat(T actual).

Casting is a solution, I agree it is not super elegant.

What I would do in that case is simply:

assertThat(myCustomException.isMyCustomFieldSet()).isTrue();

or to keep assertions on myCustomException directly:

assertThat(myCustomException).hasFieldOrPropertyWithValue("myCustomFieldSet", true)
                             .hasFieldOrPropertyWithValue("myOtherField", "foo");

The drawback here is accessing fields by name which is not refactoring friendly.

Joel Costigliola
  • 6,308
  • 27
  • 35
2

I don't think you'll be able to find a shorter way.

The issue is that

assertThat(new Player())

returns an ObjectAssert<Player>, with its matches signature being matches(Predicate<? super Player>).

However,

assertThat(new MyException())

actually calls a different method assertThat which returns an AbstractThrowableAssert<?, ? extends Throwable> with a matches(Predicate<? super Throwable>).

So that explains the issue, but I can't give you a better way to approach it.

I haven't checked whether an open issue exists against it, but it might be worth submitting one if it doesn't.

daniu
  • 14,137
  • 4
  • 32
  • 53
1

As my acknowledge, there is no way to using the method isMyCustomFieldSet directly. Because the assert lib using generic class and a generic class cannot extend the Throwable class directly or indirectly. More info here

ChickenSoups
  • 937
  • 8
  • 18