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>
,
Хотя я понимаю причину ошибки компиляции, я не согласен с ней только для метода чтения.