匹配器
IsIterableContainingInAnyOrder
对静态工厂方法containsInAnyOrder有两个重载(两者都有返回类型Matcher< java.lang.Iterable<?extends T>>):
> containsInAnyOrder(java.util.Collection< Matcher<?super T>> itemMatchers)
> containsInAnyOrder(Matcher<?super T> … itemMatchers)
现在考虑以下程序:
import static org.hamcrest.collection.IsIterableContainingInAnyOrder.containsInAnyOrder; import static org.hamcrest.core.IsEqual.equalTo; import static org.junit.Assert.assertThat; import java.util.Arrays; import org.junit.Test; public class SomeTest { @SuppressWarnings("unchecked") @Test public void foo() { assertThat(Arrays.asList("foo","bar"),containsInAnyOrder(equalTo("foo"),equalTo("bar"))); } }
当它作为JUnit测试执行时,它会按预期传递.它使用上面显示的containsInAnyOrder的第二个重载.
现在,当我将断言更改为此时(与documentation of the first overload中给出的示例完全匹配):
assertThat(Arrays.asList("foo",containsInAnyOrder(Arrays.asList(equalTo("foo"),equalTo("bar")))); ^^^^^^^^^^^^^^
它不再编译,因为现在编译器推断出containsInAnyOrder的返回类型
Matcher<Iterable<? extends List<Matcher<String>>>>
似乎编译器仍然选择第二个重载.如果它使用第一个,示例应该有效.为什么它会像这样?我怎样才能做到这一点?
我使用的是Hamcrest 1.3和Oracle Java 1.7.
解决方法
它实际上匹配两个重载方法.我不确定为什么选择第一个,但你可以提供一个提示,让它选择正确的方法.
通过将参数强制转换为Collection:
assertThat(Arrays.asList("foo",containsInAnyOrder((Collection)Arrays.asList(equalTo("foo"),equalTo("bar"))));
或者将泛型类型T指定为< String> (但不能使用静态导入):
assertThat(Arrays.asList("foo",IsIterableContainingInAnyOrder.<String>containsInAnyOrder(Arrays.asList(equalTo("foo"),equalTo("bar"))));