I've just been looking at the 'both' and 'and' methods on the org.hamcrest.core.CombinableMatcher in hamcrest 1.2
For some reason, I can't get the following to compile
@Test
public void testBoth() {
String HELLO = "hello";
String THERE = "there";
assertThat("hello there", both(containsString(HELLO)).and(containsString(THERE)));
}
The compilation message I get is
and(org.hamcrest.Matcher<? super java.lang.Object>) in org.hamcrest.core.CombinableMatcher<java.lang.Object> cannot be applied to (org.hamcrest.Matcher<java.lang.String>)
If i specify the type parameter explicity for the method, it works
@Test
public void testBoth() {
String HELLO = "hello";
String THERE = "there";
Assert.assertThat("hello there", CombinableMatcher.<String>
both(containsString(HELLO)).and(containsString(THERE)));
}
Although this is not nearly as nice.
Can anyone tell me why the compiler can't figure out the types here? I can't believe this is the expected behaviour in this case.
Thanks!
The compiler should infer LHS <: String
(§15.12.2.7 (A) then (B)) from which of course it can trivially deduce LHS = String
. JDK 7 honors the spec (and you can specify the source and target as 5 as in javac -source 5 -target
).
I hit a similar compile error (while using java 1.8 and hamcrest 1.3) because my first matcher was nullValue()
which returns type Object
.
assertThat(BigDecimal.ONE,
is(both(not(nullValue()))
.and(not(comparesEqualTo(BigDecimal.ZERO)))));
^---The method and(Matcher<? super Object>) in the type
CombinableMatcher.CombinableBothMatcher<Object> is not
applicable for the arguments (Matcher<BigDecimal>)
If you use nullValue(BigDecimal.class)
, it will compile.
assertThat(BigDecimal.ONE,
is(both(not(nullValue(BigDecimal.class)))
.and(not(comparesEqualTo(BigDecimal.ZERO)))));
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With