为什么这段代码不试图使用Hamcrest的hasItems进行编译?
为什么这不能编译,哦,该怎么办?
import static org.junit.Assert.assertThat; import static org.junit.matchers.JUnitMatchers.hasItems; ArrayList<Integer> actual = new ArrayList<Integer>(); ArrayList<Integer> expected = new ArrayList<Integer>(); actual.add(1); expected.add(2); assertThat(actual, hasItems(expected));
错误从评论复制:
cannot find symbol method assertThat(java.util.ArrayList<java.lang.Integer>, org.hamcreset.Matcher<java.lang.Iterable<java.util.ArrayList<java.lang.Integer>>>)
刚刚遇到这个post试图自己修复它。 给我足够的信息来解决这个问题。
你可以给编译器足够的说服,通过将hasItems的返回值转换成一个(原始的)Matcher来编译它,例如:
ArrayList<Integer> actual = new ArrayList<Integer>(); ArrayList<Integer> expected = new ArrayList<Integer>(); actual.add(1); expected.add(2); assertThat(actual, (Matcher) hasItems(expected));
以防其他人仍然受苦
编辑添加:尽pipe赞成票,这个答案是错误的,正如Arend指出的那样。 正确的答案是把期望变成一个整数数组,正如Hamcrest所期待的那样:
ArrayList<Integer> actual = new ArrayList<Integer>(); ArrayList<Integer> expected = new ArrayList<Integer>(); actual.add(1); expected.add(2); assertThat(actual, hasItems(expected.toArray(new Integer[expected.size()])));
hasItems检查集合是否包含一些项目,而不是两个集合是相等的,只是使用普通的相等断言。 所以要么assertEquals(a,b)要么使用assertThat
import static org.junit.Assert.assertThat; import static org.hamcrest.CoreMatchers.is; ArrayList<Integer> actual = new ArrayList<Integer>(); ArrayList<Integer> expected = new ArrayList<Integer>(); actual.add(1); expected.add(2); assertThat(actual, is(expected));
或者,使用包含匹配器,它将检查Iterable是否包含特定顺序的项目
import static org.junit.Assert.assertThat; import static org.hamcrest.Matchers.contains; ArrayList<Integer> actual = new ArrayList<Integer>(); actual.add(1); actual.add(2); assertThat(actual, contains(1, 2)); // passes assertThat(actual, contains(3, 4)); // fails
如果您不关心订单,请改用containsInAnyOrder
。
您正在比较ArrayList<Integer>
与int
。 正确的比较是:
... assertThat(actual, hasItem(2));
– 编辑 –
对不起,我读错了。 无论如何,你想要的hasItems
的签名是:
public static <T> org.hamcrest.Matcher<java.lang.Iterable<T>> hasItems(T... elements)
即它接受可变数目的参数。 我不确定一个ArrayList<T>
是否兼容,只是在这里猜测。 尝试从逗号分隔的预期列表中发送每个项目。
assertThat(actual, hasItems(2,4,1,5,6));
– 编辑2 –
只是在这里粘贴我的评论,有一个相同的expression式,你想要什么,而不使用Hamcrest:
assertTrue(actual.containsAll(expected));
尝试
assertThat(actual, hasItems(expected.toArray(new Integer[0])));
以满足匹配签名。 没有周围的Eclipse,所以这可能无法正常工作。
该错误消息看起来像由javac编译器生成的。 我发现过去用hamcrest编写的代码不会在javac下编译。 在Eclipse编译器下,相同的代码会很好的编译。
我认为Hamcrest的generics正在使用javac无法处理的generics中的angular落案例。
我刚刚遇到同样的问题,下面的技巧为我工作:
- 使用
import static org.hamcrest.Matchers.hasItems
- 在classpath中有junit的库(build path – > order and export)
你可以得到这个错误,如果你试图用一个更新的版本replacejUnit的hamcrest。 例如,将junit-dep和hamcrest 1.3一起使用需要使用来自hamcrest而不是jUnit的assert。
所以解决的办法是使用
import static org.hamcrest.MatcherAssert.assertThat;
代替
import static org.junit.Assert.assertThat;
对于这些情况下,当代码在Eclipse中编译但javac显示错误,请帮助hamcrest通过提供明确的types参数,例如Matchers.hasItem()
ArrayList<Integer> expected = new ArrayList<Integer>(); expected.add(1); expected.add(2); hasItems(expected);
hasItems(T..t)被编译器扩展为:
hasItems(new ArrayList<Integer>[]{expected});
您正在传递包含ArrayList的单个元素数组。 如果将ArrayList更改为数组,则代码将工作。
Integer[] expected = new Integer[]{1, 2}; hasItems(expected);
这将被扩展到:
hasItems(1, 2);