AssertJ `содержит точное` утверждение в списке с подстановочными знаками

У меня есть получатель, возвращающий список с подстановочным знаком:

import java.util.List;

public interface Foo {
    List<? extends Bar> getList();
}

куда Bar это другой интерфейс.

Когда я пишу утверждение с AssertJ, как это:

assertThat(foo.getList()).containsExactly(bar1, bar3);

РЕДАКТИРОВАТЬ: мое полное использование состоит в том, чтобы связать usingElementComparator и обеспечить Comparator<Bar> сравнить ожидаемое Bar экземпляров.

Comparator<Bar> comparator = createBarComparator()
assertThat(foo.getList()).usingElementComparator(comparator).containsExactly(bar1, bar3);

Я получаю эту ошибку компиляции:

Метод containsExactly(захват #46-из? Extends Bar...) в типе ListAssert не применим для аргументов (Bar, Bar)


Мое первое решение - привести результат:

assertThat((List<Bar>)foo.getList()).containsExactly(bar1, bar3);

Тогда я получаю предупреждение:

Тип безопасности: Не проверено приведение из списка в список

Предупреждение может быть удалено с @SuppressWarnings("unchecked"), но все же бросок в середине не делает утверждение действительно читабельным.


Мое второе решение состоит в том, чтобы указать значение универсального параметра ELEMENT:

Assertions.<Bar>assertThat(foo.getList()).containsExactly(bar1, bar3);

Немного лучше, но тоже не очень приятно (статический импорт невозможен, начало строки не улучшает читаемость)


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

@CheckReturnValue
public static <ELEMENT> ListAssert<ELEMENT> assertThat(List<? extends ELEMENT> actual, Class<ELEMENT> c) {
    return AssertionsForInterfaceTypes.assertThat(actual);
}

Таким образом, я смогу написать что-то вроде этого:

Assertions.assertThat(foo.getList(), Bar.class).containsExactly(bar1, bar3);

1 ответ

Раньше это работало с компилятором Oracle JDK 7, но на самом деле это была ошибка в компиляторе, это было исправлено в Java 8 JDK, поэтому наличие ошибки компиляции является нормальным поведением (хотя я не могу найти ссылку на ошибку).

Я был бы рад поддержать, но я не уверен, что это возможно в AssertJ, за исключением удаления всего использования дженериков в утверждениях коллекций.

assertThat(List, Class) уже существует, но для другой цели, так что не повезло для этого варианта.

Возможный взлом состоит в том, чтобы определить свой собственный assertThat такой метод:

public static <T> ListAssert<Object> assertThat(final List<T> list) {
    return Assertions.assertThat(list);
}

Хитрость в том, чтобы вернуть ListAssert<Object>,

Хотя я понимаю причину ошибки компиляции, я не согласен с ней только для метода чтения.

Другие вопросы по тегам