我正在学习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中产生以下错误:
没有为assertThat找到合适的方法(java.util.List,org.hamcrest.Matcher>>>) 方法org.junit.Assert.assertThat(T,org.hamcrest.Matcher)不适用 (实际参数org.hamcrest.Matcher>>>无法通过方法调用转换转换为org.hamcrest.Matcher>) 方法org.junit.Assert.assertThat(java.lang.String,T,org.hamcrest.Matcher)不适用 (无法从参数实例化,因为实际和形式参数列表的长度不同)
我知道Java 8为静态方法添加了新的隐式类型功能,我认为这可能是相关的。我试图重构参数并将它们转换为预期的参数,但这会导致相同的错误:
List<String> actual = Arrays.asList("foo", "bar");
List<Matcher<String>> expected = Arrays.asList(equalTo("foo"),
equalTo("bar"));
assertThat(actual, contains(expected));
在Java 7中调用static <E> Matcher<java.lang.Iterable<? extends E>> contains(java.util.List<Matcher<? super E>> itemMatchers)
的正确方法是什么?
答案 0 :(得分:10)
在Hamcrest Javadoc中,您定位的contains()
的方法签名是:
public static <E> Matcher<Iterable<? extends E>> contains(List<Matcher<? super E>> itemMatchers);
上述签名中需要注意的重要事项是List<Matcher<? super E>>
。 Java 7无法从List<Matcher<? super E>>
推断List<Matcher<String>>
。 contains()
还被重载,因此Java 7所针对的方法的签名是:
public static <E> Matcher<Iterable<? extends E>> contains(E... items);
这就是您收到神秘编译错误消息的原因!
幸运的是,修复非常简单:
List<String> actual = Arrays.asList("foo", "bar");
List<Matcher<? super String>> expected = Arrays.<Matcher<? super String>>asList(equalTo("foo"),
equalTo("bar"));
assertThat(actual, contains(expected));
答案 1 :(得分:0)
我没有安装库来轻松测试这个,但我认为这是一个子类型问题。
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>>
。我猜这应该解决它:
Iterable<String> actual = Arrays.asList("foo", "bar");
List<Matcher<String>> expected = Arrays.asList(equalTo("foo"),
equalTo("bar"));
assertThat(actual, contains(expected));
同样,我还没有测试过这个修复程序 - 但这似乎可以解决类型问题。