Question

I have following classes:

abstract class Answer<T> {}
class AnswerInt extends Answer<Integer> {}
class AnswerText extends Answer<String> {}

Now I'd like to use Hamcrest Matcher in following test (it's just simplified example):

@Test
public void test() {
    Answer a = new AnswerInt(5);
    assertThat(a, is(new AnswerInt(5))); // Compile error
}    

but I get compile error: The method assertThat(T, Matcher<? super T>) in the type MatcherAssert is not applicable for the arguments (Answer, Matcher<AnswerInt>).

I do understand the error message but I don't get why assertThat is defined like .. Matcher<? super T>.

Is it possible to write assertions that mix superclass and subclass?

Next, I'd like to write assertions like:

Map<String,Answer> answerMap = questionary.getAnswerMap();
assertThat(answerMap, allOf(
    hasEntry("var1", new AnswerInt(5)),
    hasEntry("var2", new AnswerText("foo"))
));

But I'm getting the same error.

I'm using Hamcrest version 1.3

Was it helpful?

Solution

If you run your test with Java 8 it compiles. For previous versions you have to give the compiler a hint:

@Test
public void test() {
    Answer a = new AnswerInt(5);
    assertThat(a, Matchers.<Answer>is(new AnswerInt(5)));
}

OTHER TIPS

I tried using equalTo(...)

assertThat(a, equalTo(new AnswerInt(5)));

What we try to do is downcast, so if you do:

assertThat(new AnswerInt(5), is(a));

Take a closer look at the message:

The method assertThat(T, Matcher<? super T>) in the type Assert is not applicable for the arguments (Answer<Integer>, Matcher<AnswerInt>)

But you actually did something like:

assertThat(<? super T>, Matcher<T>) ...
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top