Compilation error using Hamcrest everyItem()

可紊 提交于 2020-01-24 13:05:07

问题


I'm trying to use hasKey() on everyItem() in Hamcrest but I am getting the following compilation error:

error: no suitable method found for assertThat(List<Map<String,Object>>,Matcher<Iterable<Map<? extends String,?>>>)
        assertThat(data, everyItem(hasKey("index")));
        ^
    method Assert.<T#1>assertThat(T#1,Matcher<? super T#1>) is not applicable
      (actual argument Matcher<Iterable<Map<? extends String,?>>> cannot be converted to Matcher<? super List<Map<String,Object>>> by method invocation conversion)
    method Assert.<T#2>assertThat(String,T#2,Matcher<? super T#2>) is not applicable
      (cannot instantiate from arguments because actual and formal argument lists differ in length)
  where T#1,T#2 are type-variables:
    T#1 extends Object declared in method <T#1>assertThat(T#1,Matcher<? super T#1>)
    T#2 extends Object declared in method <T#2>assertThat(String,T#2,Matcher<? super T#2>)
Note: Some input files use unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.
1 error

Here is a simple JUnit test that recreates the error:

package test;

import org.junit.Test;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static org.hamcrest.collection.IsMapContaining.hasKey;
import static org.hamcrest.core.Every.everyItem;
import static org.junit.Assert.assertThat;

public class Test {

    @Test
    public void test(){
        List<Map<String, Object>> data = new ArrayList<>();
        Map<String,Object> element = new HashMap<>();
        element.put("index", 1);
        data.add(element);

        assertThat(data, everyItem(hasKey("index")));
    }



}
  • Java 1.7
  • Hamcrest 1.3
  • JUnit 4.11

Does anyone know how to resolve this compilation error?


回答1:


This is a case of nested generics.

data is currently declared as a List<Map<String, Object>>, while everyItem(hasKey("index")) is inferred as returning a Matcher<Iterable<Map<? extends String, ?>>>.

As the compilation error message states

The method assertThat(T, Matcher<? super T>) in the type Assert is not applicable for the arguments (List<Map<String,Object>>, Matcher<Iterable<Map<? extends String,?>>>)

This boils down to hasKey having a return type of Map<? extends T, ? rather than Map<T, ?>, but there's probably a good reason for that.

Fortunately, your code is simple enough that you can declare data as

List<Map<? extends String, ?>> data = new ArrayList<>();

and have the code compile.



来源:https://stackoverflow.com/questions/34169380/compilation-error-using-hamcrest-everyitem

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!