Как утвердить этот список суперклассов, равный сопоставителю подклассов, используя hamcrest и Mockito
Вопрос
Я пытаюсь сделать следующее.
final Matcher<SuperClass> matcher1 = Matchers.hasProperty("a", equalTo("b"));
final Matcher<SuperClass> matcher2 = Matchers.hasProperty("c", equalTo("d"));
final Matcher<SuperClass> matchers = Matchers.allOf(matcher1, matcher2);
List<SubClass> list = someStuff();
assertThat(list, everyItem(matchers));
Я получаю ошибку компиляции в строке утверждения, есть ли простой способ избавиться от этого.
Решение
Опция 1:
@SuppressWarnings({"unchecked", "rawtypes"})
@Test public void yourTest() {
final Matcher<SuperClass> matcher1 = Matchers.hasProperty("a", equalTo("b"));
final Matcher<SuperClass> matcher2 = Matchers.hasProperty("c", equalTo("d"));
final Matcher<SuperClass> matchers = Matchers.allOf(matcher1, matcher2);
List<SubClass> list = someStuff();
// Note cast to raw type here, corresponding to the suppressed warnings.
assertThat(list, (Matcher) everyItem(matchers));
}
Вариант 2:
// These are all of type Matcher<SubClass> instead.
final Matcher<SubClass> matcher1 = Matchers.hasProperty("a", equalTo("b"));
final Matcher<SubClass> matcher2 = Matchers.hasProperty("c", equalTo("d"));
final Matcher<SubClass> matchers = Matchers.allOf(matcher1, matcher2);
List<SubClass> list = someStuff();
assertThat(list, everyItem(matchers));
Почему? Обработка дженериков в Java слишком умна для Hamcrest. everyItem(matchers)
вернет Matcher<Iterable<SuperClass>>
, но у вас нет Iterable<SuperClass>
, у тебя есть Iterable<SubClass>
.Все было бы хорошо, если бы ваши методы Matcher действительно создавали Matcher<Iterable<? extends SuperClass>>
, но вам практически невозможно убедить Java, что ваш matcher1
и matcher2
совместимы друг с другом.
Другие советы
Generics.
The problem with your code is that you try to assert that a list with type List<SubClass>
matches every item of a matcher with type Matcher<SuperClass>
.
Even though SuperClass
extends SubClass
, the assertThat
method requires the two to be the same.
So if you can coerce your someStuff()
method to return a list of of SuperClass
, you should be home free. I.e. something like this
List<SuperClass> list = someStuff();
assertThat(list, everyItem(matchers));
would get rid of the compilation error.