Соответствие пользовательских исключений - PullRequest
1 голос
/ 31 января 2020

Javado c дает этот пример для метода matches:

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

И действительно, когда я определяю фиктивный класс Player, вышеприведенный оператор компилируется нормально. Однако, когда я определяю класс, производный от Exception, следующее не компилируется:

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

Я могу заставить его скомпилировать, используя приведение:

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

, но это актерский состав выглядит «некрасиво» и немного хакерски, чтобы обойти какой-то недостаток. Могу ли я заставить его скомпилироваться «лучше», то есть без использования приведения?

Ответы [ 3 ]

2 голосов
/ 31 января 2020

Не думаю, что вы сможете найти более короткий путь.

Проблема в том, что

assertThat(new Player())

возвращает ObjectAssert<Player> с его подписью matches быть matches(Predicate<? super Player>).

Однако

assertThat(new MyException())

фактически вызывает другой метод assertThat, который возвращает AbstractThrowableAssert<?, ? extends Throwable> с matches(Predicate<? super Throwable>).

Так что это объясняет проблему, но Я не могу дать вам лучший способ приблизиться к нему.

Я не проверял, существует ли открытая проблема против него, но, возможно, стоит отправить его, если его нет.

1 голос
/ 01 февраля 2020

Проблема в Assertions, она объявляет AbstractThrowableAssert<?, ? extends Throwable> assertThat(Throwable t) вместо <T> AbstractThrowableAssert<?, T extends Throwable> assertThat(T t)

Но, к сожалению, это невозможно сделать из-за следующего существующего метода, который конфликтует с ним: public static <T> ObjectAssert<T> assertThat(T actual).

Кастинг - это решение, я согласен, что оно не очень изящно.

В этом случае я бы просто сделал:

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

или оставить утверждения на myCustomException напрямую:

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

Недостатком здесь является доступ к полям по имени, что не способствует рефакторингу.

1 голос
/ 31 января 2020

Как я понимаю, нет способа напрямую использовать метод isMyCustomFieldSet . Поскольку библиотека assert, использующая класс generi c и класс generi c, не может прямо или косвенно расширять класс Throwable. Подробнее здесь

...