为什么没有这个代码试图使用Hamcrest的hasItems编译?(Why doesn't

2019-06-25 06:42发布

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

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

Answer 1:

恰好碰到了这个帖子试图修复它自己。 给了我足够的信息去解决它。

你可以给编译器就足以说服它通过从铸造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()])));


Answer 2:

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

或者,使用含有匹配器,其检查,一个可迭代包含以特定的顺序的项目

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代替。



Answer 3:

您比较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));


Answer 4:

尝试

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

以满足匹配的签名。 没有Eclipse的周围,所以这可能无法正常工作。



Answer 5:

该错误消息看起来像一个由javac编译器产生。 我已经在过去的代码使用hamcrest是不会下的javac编译书面发现。 相同的代码可以编译精细下,说,Eclipse编译器。

我认为Hamcrest仿制药正在行使的角落案件在javac是无法对付仿制药。



Answer 6:

我刚刚遇到了同样的问题,下面的技巧为我工作:

  • 采用import static org.hamcrest.Matchers.hasItems
  • 在类路径的JUnit之前有hamcrest库(建设路 - >订单和出口)


Answer 7:

如果你尝试用一个较新的版本替换JUnit的hamcrest你可以得到这个错误。 例如,使用的junit-DEP一起hamcrest 1.3要求使用assertThat从hamcrest代替JUNIT。

因此,解决方案是使用

import static org.hamcrest.MatcherAssert.assertThat;

代替

import static org.junit.Assert.assertThat;



Answer 8:

对于这些情况,当代码不会编译在Eclipse但javac的显示错误,请通过提供明确的类型做帮助hamcrest参数如Matchers.hasItem()



Answer 9:

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


文章来源: Why doesn't this code attempting to use Hamcrest's hasItems compile?