为什么尝试使用 Hamcrest 的 hasItems 的代码无法编译?

发布于 2024-07-26 11:56:52 字数 585 浏览 15 评论 0原文

为什么这个不能编译,哦,怎么办?

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>>>)

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>>>)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(9

不一样的天空 2024-08-02 11:56:52

刚刚遇到这篇文章,试图为自己修复它。 给了我足够的信息来解决这个问题。

您可以通过将 hasItems 的返回值转换为(原始)匹配器来为编译器提供足够的信息来说服它进行编译,例如:

ArrayList<Integer> actual = new ArrayList<Integer>();
ArrayList<Integer> expected = new ArrayList<Integer>();
actual.add(1);
expected.add(2);
assertThat(actual, (Matcher) hasItems(expected));

以防万一其他人仍在遭受痛苦......

编辑添加:
尽管获得了赞成票,但这个答案是错误的,正如阿伦德在下面指出的那样。 正确的答案是将预期值转换为整数数组,正如 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()])));

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:

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 correct answer is to turn the expected into an array of Integers, as hamcrest is expecting:

    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()])));
雨巷深深 2024-08-02 11:56:52

hasItems 检查一个集合是否包含某些项目,而不是检查两个集合是否相等,只需使用正常的相等断言即可。 因此,要么使用assertEquals(a, b),要么

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));

使用assertThat,或者使用contains Matcher,它会检查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。

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

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

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.

谎言 2024-08-02 11:56:52

您正在将 ArrayListint 进行比较。 正确的比较是:

...
assertThat(actual, hasItem(2));

-- 编辑 --

对不起,我读错了。 无论如何,您想要的 hasItems 的签名是:

public static <T> org.hamcrest.Matcher<java.lang.Iterable<T>> hasItems(T... elements)

即,它接受可变数量的参数。 我不确定 ArrayList是否兼容,只是在这里猜测。 尝试发送预期列表中的每个项目,并用逗号分隔。

assertThat(actual, hasItems(2,4,1,5,6));

-- 编辑 2 --

只需将我的评论粘贴到此处,您想要的内容有一个等效的表达式,无需使用 Hamcrest:

assertTrue(actual.containsAll(expected));

You are comparing ArrayList<Integer> with int. The correct comparison is:

...
assertThat(actual, hasItem(2));

-- Edit --

I'm sorry, I've read it wrong. Anyway, the signature of hasItems you want is:

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.

assertThat(actual, hasItems(2,4,1,5,6));

-- Edit 2 --

Just pasting here my comment, there is an equivalent expression for what you want, without using Hamcrest:

assertTrue(actual.containsAll(expected));
离不开的别离 2024-08-02 11:56:52

尝试

assertThat(actual, hasItems(expected.toArray(new Integer[0])));

满足匹配器签名。 周围没有 Eclipse,所以这可能不起作用。

Try

assertThat(actual, hasItems(expected.toArray(new Integer[0])));

to satisfy the matcher signature. No Eclipse around, so this might not work.

嘦怹 2024-08-02 11:56:52

该错误消息看起来像是由 javac 编译器生成的错误消息。 我过去发现使用 hamcrest 编写的代码无法在 javac 下编译。 相同的代码在 Eclipse 编译器下可以很好地编译。

我认为 Hamcrest 的泛型正在处理 javac 无法处理的泛型中的极端情况。

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.

I think Hamcrest's generics are exercising corner cases in generics that javac can't deal with.

只想待在家 2024-08-02 11:56:52

我刚刚遇到了同样的问题,以下技巧对我有用:

  • 使用 import static org.hamcrest.Matchers.hasItems
  • 在类路径中的 junit 之前拥有 hamcrest 库(构建路径 -> 顺序和导出)

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)
撕心裂肺的伤痛 2024-08-02 11:56:52

如果您尝试用更新版本替换 jUnit 的 hamcrest,您可能会收到此错误。 例如,将 junit-dep 与 hamcrest 1.3 一起使用需要使用 hamcrest 中的assertThat 而不是 jUnit。

所以解决方案是使用

import static org.hamcrest.MatcherAssert.assertThat;

而不是

import static org.junit.Assert.assertThat;

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.

So the solution is to use

import static org.hamcrest.MatcherAssert.assertThat;

instead of

import static org.junit.Assert.assertThat;

感悟人生的甜 2024-08-02 11:56:52

对于这些情况,当代码在 Eclipse 中编译但 javac 显示错误时,请通过显式提供类型参数来帮助 hamcrest,例如
Matchers.hasItem()

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()

找回味觉 2024-08-02 11:56:52
ArrayList<Integer> expected = new ArrayList<Integer>();
expected.add(1);
expected.add(2);
hasItems(expected);

hasItems(T..t) 被编译器扩展为:

hasItems(new ArrayList<Integer>[]{expected});

您正在传递一个包含 ArrayList 的单元素数组。 如果将 ArrayList 更改为 Array,那么您的代码就可以工作。

Integer[] expected = new Integer[]{1, 2};
hasItems(expected);

这将扩展到:

hasItems(1, 2);
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(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.

Integer[] expected = new Integer[]{1, 2};
hasItems(expected);

This will be expanded to:

hasItems(1, 2);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文