javagenericstestinghamcrest

Compilation error when trying to combine hamcrest matchers


I have a Queue of string and I want to combine 2 matchers in a single assert The (simplified) code is something like this

    Queue<String> strings = new LinkedList<>();
    assertThat(strings, both(hasSize(1)).and(hasItem("Some string")));

but when I compile it I get the following message:

incompatible types: no instance(s) of type variable(s) T exist so that org.hamcrest.Matcher<java.lang.Iterable<? super T>> conforms to org.hamcrest.Matcher<? super java.util.Collection<? extends java.lang.Object>>

how can I resolve this?


Solution

  • Both of the matchers must conform to ...

    Matcher<? super LHS> matcher
    

    ... where LHS is a Collection<?> because strings is a Collection<?>.

    In your code hasSize(1) is a Matcher<Collection<?>> but hasItem("Some string") is a Matcher<Iterable<? super String>> hence the compilation error.

    This example uses a combinable matcher and it is compilable because both matchers address a collection ...

    assertThat(strings, either(empty()).or(hasSize(1)));
    

    But given the method signature of both() you cannot combine hasSize() and hasItem().

    The combinable matcher is just a short cut so perhaps you could replace it with two assertions:

    assertThat(strings, hasSize(1));
    assertThat(strings, hasItem("Some string"));