为什么这段代码没有尝试使用Hamcrest的hasItems编译?

rip*_*234 55 java junit unit-testing hamcrest matcher

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

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));
Run Code Online (Sandbox Code Playgroud)

从评论中复制的错误:

cannot find symbol method assertThat(java.util.ArrayList<java.lang.Integer>, org.hamcreset.Matcher<java.lang.Iterable<java.util.ArrayList<java.lang.Integer>>>)
Run Code Online (Sandbox Code Playgroud)

Cli*_*ans 53

刚试过这篇文章试图为自己修复它.给我足够的信息来解决它.

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

ArrayList<Integer> actual = new ArrayList<Integer>();
ArrayList<Integer> expected = new ArrayList<Integer>();
actual.add(1);
expected.add(2);
assertThat(actual, (Matcher) hasItems(expected));
Run Code Online (Sandbox Code Playgroud)

以防其他任何人仍在受苦......

编辑添加:尽管投票很多,但这个答案是错误的,正如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()])));
Run Code Online (Sandbox Code Playgroud)

  • 这是**错误的**.这个答案检查`actual`是否包含List`expected`,而不是`actual`包含List`expected`的元素.尝试使用`expected.add(1)`代替:此代码永远不会通过.编译错误有一个很好的理由.用演员表来压制它并不是一个好主意. (19认同)
  • Yeees,至少可以说,让我继续进行测试通过是令人困惑的._correct_的答案是: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()]))); (2认同)

小智 22

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));
Run Code Online (Sandbox Code Playgroud)

或者,使用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
Run Code Online (Sandbox Code Playgroud)

如果您不关心订单的使用containsInAnyOrder.


fre*_*ass 12

你是比较ArrayList<Integer>int.正确的比较是:

...
assertThat(actual, hasItem(2));
Run Code Online (Sandbox Code Playgroud)

- 编辑 -

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

public static <T> org.hamcrest.Matcher<java.lang.Iterable<T>> hasItems(T... elements)
Run Code Online (Sandbox Code Playgroud)

即,它接受可变数量的参数.我不确定是否ArrayList<T>兼容,只是在这里猜测.尝试发送散布在逗号中的预期列表中的每个项目.

assertThat(actual, hasItems(2,4,1,5,6));
Run Code Online (Sandbox Code Playgroud)

- 编辑2 -

只要粘贴我的评论,就可以在不使用Hamcrest的情况下提供相应的表达式:

assertTrue(actual.containsAll(expected));
Run Code Online (Sandbox Code Playgroud)

  • 它更简单,但是当这个断言失败时,你会得到一个非常神秘的错误消息,这比我想象的hasItems输出的错误消息更有帮助. (3认同)