Почему нельзя использовать assertThat(map1, sameInstance(map2))?

С новой грамматикой Assert при проверке подлинности можно было бы написать

Assert.assertThat(obj1, CoreMatchers.sameInstance(obj2))

вместо

Assert.assertSame(obj1, obj2)

Я пытаюсь подтвердить личность карты. Так что я пишу

Assert.assertThat(map1, CoreMatchers.sameInstance(map2))

где карта имеет тип HashMap<String,String> Но мои тесты терпят неудачу во время компиляции:

Error:(33, 9) error: no suitable method found for assertThat(Map,Matcher<Map<String,String>>)
method Assert.<T#1>assertThat(String,T#1,Matcher<? super T#1>) is not applicable
(cannot infer type-variable(s) T#1
(actual and formal argument lists differ in length))
method Assert.<T#2>assertThat(T#2,Matcher<? super T#2>) is not applicable
(cannot infer type-variable(s) T#2
(argument mismatch; Matcher<Map<String,String>> cannot be converted to Matcher<? super Map>))
where T#1,T#2 are type-variables:
T#1 extends Object declared in method <T#1>assertThat(String,T#1,Matcher<? super T#1>)
T#2 extends Object declared in method <T#2>assertThat(T#2,Matcher<? super T#2>)
Error:(33) error: no suitable method found for assertThat(Map,Matcher<Map<String,String>>)

Почему JUnit (или Hamcrest) не может определить, какой сопоставитель использовать?


person Some Noob Student    schedule 14.04.2015    source источник
comment
Является ли map1 необработанным Map или Map<String, String>? Если это необработанный Map, вероятно, этого не должно быть.   -  person user2357112 supports Monica    schedule 14.04.2015
comment
Сбой во время выполнения? Это похоже на ошибку времени компиляции. Как объявляются map1 и map2?   -  person Jesper    schedule 14.04.2015
comment
Ой! Он терпит неудачу во время компиляции.   -  person Some Noob Student    schedule 14.04.2015


Ответы (1)


Оказывается, это не имеет ничего общего с подтверждением подлинности карты — код был правильным — но имеет какое-то отношение к дженерикам.

Класс, который я пытался протестировать, выглядел примерно так:

public class Response<T>{
    public final Map<String, String> map;
    public final T data;
}

Однако тест был написан так:

@Test
public void testStuff() throws Exception {
    Map<String, String> map = new HashMap<>();
    Object data = new Object();
    Response target = new Response<>(map, data);
    assertThat(target.map, sameInstance(map));
    assertThat(target.data, sameInstance(data));
}

Ошибка компиляции на самом деле в последней строке, потому что T (<?>) неизвестен компилятору, он не смог найти подходящий сопоставитель. Я исправил тест, объявив необработанный тип.

@Test
public void testStuff() throws Exception {
    Map<String, String> map = new HashMap<>();
    Object data = new Object();
    Response<Object> target = new Response<>(map, data);
    assertThat(target.map, sameInstance(map));
    assertThat(target.data, sameInstance(data));
}

Но мне кажется странным, почему компилятор жалуется на предыдущую строку...

person Some Noob Student    schedule 14.04.2015
comment
Если вы используете необработанный Response, его переменные экземпляра также являются необработанными типами, даже если параметры типа Response не задействованы. target.map является необработанным, если target является. - person user2357112 supports Monica; 14.04.2015
comment
Очаровательный! Спасибо за понимание! - person Some Noob Student; 14.04.2015