Java 为什么尝试使用 Hamcrest 的 hasItems 的代码不能编译?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1092981/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Why doesn't this code attempting to use Hamcrest's hasItems compile?
提问by ripper234
Why does this not compile, oh, what to do?
这个怎么不编译啊,怎么办?
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));
error copied from comment:
从评论中复制的错误:
cannot find symbol method assertThat(java.util.ArrayList<java.lang.Integer>, org.hamcreset.Matcher<java.lang.Iterable<java.util.ArrayList<java.lang.Integer>>>)
回答by freitass
You are comparing ArrayList<Integer>
with int
. The correct comparison is:
您正在ArrayList<Integer>
与int
. 正确的比较是:
...
assertThat(actual, hasItem(2));
-- Edit --
- 编辑 -
I'm sorry, I've read it wrong. Anyway, the signature of hasItems
you want is:
对不起,我读错了。不管怎样,hasItems
你想要的签名是:
public static <T> org.hamcrest.Matcher<java.lang.Iterable<T>> hasItems(T... elements)
i.e., it accepts a variable number of arguments. I'm not sure if an ArrayList<T>
is compatible, just guessing here. Try sending each item from the expected list interspersed by comma.
即,它接受可变数量的参数。我不确定 anArrayList<T>
是否兼容,只是在这里猜测。尝试发送预期列表中的每个项目,并用逗号穿插。
assertThat(actual, hasItems(2,4,1,5,6));
-- Edit 2 --
-- 编辑 2 --
Just pasting here my comment, there is an equivalent expression for what you want, without using Hamcrest:
只是在这里粘贴我的评论,你想要的有一个等价的表达,不使用 Hamcrest:
assertTrue(actual.containsAll(expected));
回答by skaffman
That error message looks like one produced by the javac compiler. I've found in the past that code written using hamcrest just won't compile under javac. The same code will compile fine under, say, the Eclipse compiler.
该错误消息看起来像是由 javac 编译器生成的。我过去发现使用 hamcrest 编写的代码无法在 javac 下编译。相同的代码在 Eclipse 编译器下也能很好地编译。
I think Hamcrest's generics are exercising corner cases in generics that javac can't deal with.
我认为 Hamcrest 的泛型正在使用 javac 无法处理的泛型中的极端情况。
回答by Robert Munteanu
Try
尝试
assertThat(actual, hasItems(expected.toArray(new Integer[0])));
to satisfy the matcher signature. No Eclipse around, so this might not work.
以满足匹配器签名。周围没有 Eclipse,所以这可能不起作用。
回答by Dan Godfrey
hasItems checks that a collection contains some items, not that 2 collections are equal, just use the normal equality assertions for that. So either assertEquals(a, b) or using assertThat
hasItems 检查一个集合是否包含一些项目,而不是 2 个集合是否相等,只需使用正常的相等断言即可。所以要么 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));
Alternatively, use the contains Matcher, which checks that an Iterable contains items in a specific order
或者,使用 contains Matcher,它检查可迭代对象是否包含特定顺序的项目
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
If you don't care about the order use containsInAnyOrder
instead.
如果您不关心订单,请containsInAnyOrder
改用。
回答by User109377
ArrayList<Integer> expected = new ArrayList<Integer>();
expected.add(1);
expected.add(2);
hasItems(expected);
hasItems(T..t) is being expanded by the compiler to:
hasItems(T..t) 正在被编译器扩展为:
hasItems(new ArrayList<Integer>[]{expected});
You are passing a single element array containing an ArrayList. If you change the ArrayList to an Array, then your code will work.
您正在传递一个包含 ArrayList 的单元素数组。如果您将 ArrayList 更改为 Array,则您的代码将起作用。
Integer[] expected = new Integer[]{1, 2};
hasItems(expected);
This will be expanded to:
这将扩展为:
hasItems(1, 2);
回答by miluch
For these cases when code does compile in Eclipse but javac shows errors please do help hamcrest by providing explicitly type parameter e.g. Matchers.hasItem()
对于代码在 Eclipse 中编译但 javac 显示错误的这些情况,请通过提供显式类型参数(例如 Matchers.hasItem())来帮助 hamcrest
回答by Zsolt
I just came across the same problem and the following trick worked for me:
我刚刚遇到了同样的问题,以下技巧对我有用:
- use
import static org.hamcrest.Matchers.hasItems
- have the hamcrest library before junit in classpath (build path -> order and export)
- 用
import static org.hamcrest.Matchers.hasItems
- 在类路径中的 junit 之前拥有 hamcrest 库(构建路径 -> 订购和导出)
回答by Clive Evans
Just ran into this post trying to fix it for myself. Gave me just enough information to work it out.
刚刚遇到这篇文章,试图为自己修复它。给了我足够的信息来解决它。
You can give the compiler just enough to persuade it to compile by casting the return value from hasItems to a (raw) Matcher, eg:
您可以通过将 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));
Just in case anybody else is still suffering ...
以防万一其他人还在受苦……
Edit to add: In spite of the up votes, this answer is wrong, as Arend points out below. The correctanswer is to turn the expected into an array of Integers, as hamcrest is expecting:
编辑添加:尽管投票赞成,但正如 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()])));
回答by Mika
You can get this error if you try to replace jUnit's hamcrest with a newer version. For example, using junit-dep together with hamcrest 1.3 requires that use assertThat from hamcrest instead of jUnit.
如果您尝试用较新版本替换 jUnit 的 hamcrest,您可能会收到此错误。例如,将 junit-dep 与 hamcrest 1.3 一起使用需要使用来自 hamcrest 的 assertThat 而不是 jUnit。
So the solution is to use
所以解决方案是使用
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.MatcherAssert.assertThat;
instead of
代替
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertThat;