Search code examples
javajunithamcrest

How to use hamcrest contains to compare 2 lists?


Why does this test fail? I know contains works when you pass in individual strings separated by commas but I wanted to see if it's possible to just pass in an entire list of strings instead. I just want to make sure that list 1 contains all of the contents of list 2.

@Test
public void testContains() {
    String expected1 = "hello";
    String expected2 = "goodbye";
    List<String> expectedStrings = new ArrayList<>();
    expectedStrings.add(expected1);
    expectedStrings.add(expected2);
    List<String> actualStrings = new ArrayList<>();
    actualStrings.add(expected1);
    actualStrings.add(expected2);
    assertThat(actualStrings, contains(expectedStrings));
}

Is it considered acceptable to use this assertion instead?

assertThat(actualStrings, is(expectedStrings));

Solution

  • There is no overloaded contains method which takes a list of expected values.

    In the statement assertThat(actualStrings, contains(expectedStrings)) the following method (in the Matchers class) is called:

    <E> org.hamcrest.Matcher<java.lang.Iterable<? extends E>> contains(E... items)
    

    Basically you are saying that you expect a list with one element and this element is expectedStrings but in fact it is expected1 (E is of type List<String> and not String). To verify add the following to the test which should then pass:

    List<List<String>> listOfactualStrings = new ArrayList<>();
    listOfactualStrings.add(actualStrings);
    assertThat(listOfactualStrings, contains(expectedStrings));
    

    To make the assertion work you have to convert the list to an array:

    assertThat(actualStrings, contains(expectedStrings.toArray()));