Why doesn't this code attempting to use Hamcrest's hasItems compile?

前端 未结 9 1723
耶瑟儿~
耶瑟儿~ 2020-12-03 00:49

Why does this not compile, oh, what to do?

import static org.junit.Assert.assertThat;
import static org.junit.matchers.JUnitMatchers.hasItems;

ArrayList<         


        
相关标签:
9条回答
  • 2020-12-03 00:50
    ArrayList<Integer> expected = new ArrayList<Integer>();
    expected.add(1);
    expected.add(2);
    hasItems(expected);
    

    hasItems(T..t) is being expanded by the compiler to:

    hasItems(new ArrayList<Integer>[]{expected});
    

    You are passing a single element array containing an ArrayList. If you change the ArrayList to an Array, then your code will work.

    Integer[] expected = new Integer[]{1, 2};
    hasItems(expected);
    

    This will be expanded to:

    hasItems(1, 2);
    
    0 讨论(0)
  • 2020-12-03 00:52

    Try

    assertThat(actual, hasItems(expected.toArray(new Integer[0])));
    

    to satisfy the matcher signature. No Eclipse around, so this might not work.

    0 讨论(0)
  • 2020-12-03 00:52

    I just came across the same problem and the following trick worked for me:

    • use import static org.hamcrest.Matchers.hasItems
    • have the hamcrest library before junit in classpath (build path -> order and export)
    0 讨论(0)
  • 2020-12-03 00:52

    For these cases when code does compile in Eclipse but javac shows errors please do help hamcrest by providing explicitly type parameter e.g. Matchers.hasItem()

    0 讨论(0)
  • 2020-12-03 00:53

    You are comparing ArrayList<Integer> with int. The correct comparison is:

    ...
    assertThat(actual, hasItem(2));
    

    -- Edit --

    I'm sorry, I've read it wrong. Anyway, the signature of hasItems you want is:

    public static <T> org.hamcrest.Matcher<java.lang.Iterable<T>> hasItems(T... elements)
    

    i.e., it accepts a variable number of arguments. I'm not sure if an ArrayList<T> is compatible, just guessing here. Try sending each item from the expected list interspersed by comma.

    assertThat(actual, hasItems(2,4,1,5,6));
    

    -- Edit 2 --

    Just pasting here my comment, there is an equivalent expression for what you want, without using Hamcrest:

    assertTrue(actual.containsAll(expected));
    
    0 讨论(0)
  • 2020-12-03 00:54

    Just ran into this post trying to fix it for myself. Gave me just enough information to work it out.

    You can give the compiler just enough to persuade it to compile by casting the return value from hasItems to a (raw) Matcher, eg:

    ArrayList<Integer> actual = new ArrayList<Integer>();
    ArrayList<Integer> expected = new ArrayList<Integer>();
    actual.add(1);
    expected.add(2);
    assertThat(actual, (Matcher) hasItems(expected));
    

    Just in case anybody else is still suffering ...

    Edit to add: In spite of the up votes, this answer is wrong, as Arend points out below. The correct answer is to turn the expected into an array of Integers, as hamcrest is expecting:

        ArrayList<Integer> actual = new ArrayList<Integer>();
        ArrayList<Integer> expected = new ArrayList<Integer>();
        actual.add(1);
        expected.add(2);
        assertThat(actual, hasItems(expected.toArray(new Integer[expected.size()])));
    
    0 讨论(0)
提交回复
热议问题