hamcrest我怎样才能得到contains(List<Matcher>itemmachers)来用Java 7编译?
我正在学习Hamcrest 1.3,我想为Matchers中的每个Hamcrest静态方法提供一个示例。Javadoc已经有了一些方法的示例,这很有帮助。我用Java 8测试了以下contains代码片段,结果通过了测试:
assertThat(Arrays.asList("foo", "bar"),
contains(Arrays.asList(equalTo("foo"), equalTo("bar"))));
然而,我的团队目前正在使用Java 7,所以我希望确保所有示例都能在该版本中工作。上述代码片段在Java 7中产生以下错误:
no suitable method found for assertThat(java.util.List,org.hamcrest.Matcher>>>) method org.junit.Assert.assertThat(T,org.hamcrest.Matcher) is not applicable (actual argument org.hamcrest.Matcher>>> cannot be converted to org.hamcrest.Matcher> by method invocation conversion) method org.junit.Assert.assertThat(java.lang.String,T,org.hamcrest.Matcher) is not applicable (cannot instantiate from arguments because actual and formal argument lists differ in length)
我知道Java8为静态方法添加了新的隐式类型特性,我认为这可能与此有关。我试图重构参数并将其转换为预期参数,但这会导致相同的错误:
List<String> actual = Arrays.asList("foo", "bar");
List<Matcher<String>> expected = Arrays.asList(equalTo("foo"),
equalTo("bar"));
assertThat(actual, contains(expected));
在Java7中调用static <E> Matcher<java.lang.Iterable<? extends E>> contains(java.util.List<Matcher<? super E>> itemMatchers)
的正确方法是什么
# 1 楼答案
在Hamcrest Javadoc中,针对
contains()
的方法签名是:在上面的签名中需要注意的重要一点是
List<Matcher<? super E>>
。Java 7无法从List<Matcher<String>>
推断List<Matcher<? super E>>
。另外contains()
被重载,因此Java 7所针对的方法的签名是:这就是为什么你会收到神秘的编译错误信息
幸运的是,解决方法非常简单:
# 2 楼答案
我没有安装库来测试这一点,但我认为这是一个子类型问题
expected
具有类型List<Matcher<String>>
contains(expected)
有类型Matcher<Iterable<String>>
actual
有类型List<String>
assertThat
需要类型为T
的第一个参数和类型为Matcher<T>
的第二个参数T
是List<String>
,这意味着它需要类型为Matcher<List<String>>
的第二个参数,而不是Matcher<Iterable<String>>
李>我猜这应该可以解决这个问题:
再说一次,我还没有测试这个补丁,但它似乎可以解决类型问题