Как я могу получить contains(список itemMatchers) для компиляции в Java 7?
Я изучаю Hamcrest 1.3 и хочу придумать пример для каждого статического метода Hamcrest вMatchers . Javadoc услужливо уже имеет примеры для некоторых методов. Я протестировал следующийсодержит фрагмент кода с Java 8, и он прошел:
assertThat(Arrays.asList("foo", "bar"),
contains(Arrays.asList(equalTo("foo"), equalTo("bar"))));
Тем не менее, моя команда в настоящее время использует Java 7, поэтому я хотел убедиться, что все примеры работают в этой версии. Приведенный выше фрагмент кода приводит к следующей ошибке в Java 7:
Нет подходящего метода найдено для assertThat(java.утиль.Список, орг.hamcrest.Совпадение>>>) метод орг.тесты JUnit.Утверждать.assertThat(T, орг.hamcrest.Совпадений) не применяется (фактический аргумент орг.hamcrest.Matcher > > > не может быть преобразован в org.hamcrest.Matcher> по методу преобразования вызова) метод орг.тесты JUnit.Утверждать.assertThat (Ява.яз..Строка, Т, орг.hamcrest.Совпадений) не применяется (невозможно создать экземпляр из аргументов, поскольку фактические и формальные списки аргументов отличаются по длине)
Я знаю. что Java 8 добавила новые неявные функции типирования для статических методов, и я думаю, что это, вероятно, связано. Я попытался рефакторировать параметры и привести их к ожидаемым аргументам, но это приводит к той же ошибке:
List<String> actual = Arrays.asList("foo", "bar");
List<Matcher<String>> expected = Arrays.asList(equalTo("foo"),
equalTo("bar"));
assertThat(actual, contains(expected));
Как правильно вызывать static <E> Matcher<java.lang.Iterable<? extends E>> contains(java.util.List<Matcher<? super E>> itemMatchers)
в Java 7?
2 ответа:
В Hamcrest Javadoc сигнатура метода для
contains()
, на который вы нацелены, является:public static <E> Matcher<Iterable<? extends E>> contains(List<Matcher<? super E>> itemMatchers);
Важным битом, который следует отметить в приведенной выше сигнатуре, является
List<Matcher<? super E>>
. Java 7 не может вывестиList<Matcher<? super E>>
изList<Matcher<String>>
.contains()
дополнительно перегружен, поэтому сигнатура метода, который нацелен на Java 7, является:public static <E> Matcher<Iterable<? extends E>> contains(E... items);
И именно по этой причине вы получаете сообщение об ошибке компиляции cryptic!
К счастью, исправление довольно простое:
List<String> actual = Arrays.asList("foo", "bar"); List<Matcher<? super String>> expected = Arrays.<Matcher<? super String>>asList(equalTo("foo"), equalTo("bar")); assertThat(actual, contains(expected));
У меня нет установленных библиотек, чтобы легко проверить это, но я думаю, что это проблема подтипов.
expected
имеет типList<Matcher<String>>
contains(expected)
имеет типMatcher<Iterable<String>>
actual
имеет типList<String>
assertThat
требуется первый аргумент типаT
и второй типаMatcher<T>
- Ваш
T
являетсяList<String>
, что означает, что он ожидает второй аргумент типаMatcher<List<String>>
, а неMatcher<Iterable<String>>
.Я предполагаю, что это должно исправить это:
Iterable<String> actual = Arrays.asList("foo", "bar"); List<Matcher<String>> expected = Arrays.asList(equalTo("foo"), equalTo("bar")); assertThat(actual, contains(expected));
Опять же, я этого не сделал. протестировал это исправление-но похоже, что оно прояснит проблемы типа.