55

这个怎么编译不出来啊,怎么办?

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

9 回答 9

55

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

您可以通过将返回值从 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()])));
于 2011-09-07T13:49:14.483 回答
22

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

或者,使用 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改用。

于 2009-10-28T10:53:34.597 回答
12

您正在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 --

只需在此处粘贴我的评论,就可以在不使用 Hamcrest 的情况下使用您想要的等效表达式:

assertTrue(actual.containsAll(expected));
于 2009-07-07T15:29:07.303 回答
3

尝试

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

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

于 2009-07-07T22:11:14.530 回答
2

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)
于 2011-03-10T22:01:20.833 回答
2

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

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

于 2009-07-07T21:41:56.320 回答
2

如果您尝试将 jUnit 的 hamcrest 替换为较新的版本,则会出现此错误。例如,将 junit-dep 与 hamcrest 1.3 一起使用需要使用 hamcrest 中的 assertThat 而不是 jUnit。

所以解决方案是使用

import static org.hamcrest.MatcherAssert.assertThat;

代替

import static org.junit.Assert.assertThat;

于 2013-02-25T12:37:02.117 回答
1

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

于 2011-02-03T10:16:01.053 回答
0
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);
于 2010-10-12T17:01:29.403 回答