Java 检查Hamcrest中的列表是否为空

Java 检查Hamcrest中的列表是否为空,java,collections,junit,hamcrest,Java,Collections,Junit,Hamcrest,我想知道是否有人知道使用assertThat()和Matchers检查列表是否为空的方法 我能看到的最好方法就是使用JUnit: assertFalse(list.isEmpty()); 但我希望在汉克雷斯特能有办法做到这一点。嗯,总是有办法的 assertThat(list.isEmpty(), is(false)); 。。。但我猜这不是你的意思:) 或者: assertThat((Collection)list, is(not(empty()))); empty()在Matchers类

我想知道是否有人知道使用
assertThat()
Matchers
检查列表是否为空的方法

我能看到的最好方法就是使用JUnit:

assertFalse(list.isEmpty());
但我希望在汉克雷斯特能有办法做到这一点。

嗯,总是有办法的

assertThat(list.isEmpty(), is(false));
。。。但我猜这不是你的意思:)

或者:

assertThat((Collection)list, is(not(empty())));
empty()
Matchers
类中是静态的。注意需要将
列表
转换为
集合
,这要归功于Hamcrest 1.2的古怪泛型

以下进口产品可用于hamcrest 1.3

import static org.hamcrest.Matchers.empty;
import static org.hamcrest.core.Is.is;
import static org.hamcrest.core.IsNot.*;

这在Hamcrest 1.3中已固定。以下代码编译后不会生成任何警告:

// given
List<String> list = new ArrayList<String>();
// then
assertThat(list, is(not(empty())));
上述解决方案最重要的一点是,它不会生成任何警告。
如果您希望估计最小结果大小,则第二种解决方案更为有用。

如果您正在查找可读的失败消息,则可以使用带有空列表的常规assertEquals,不使用hamcrest:

assertEquals(new ArrayList<>(0), yourList);
创建您自己的自定义IsEmpty TypeSafeMatcher: 即使泛型问题在
1.3
中得到了解决,该方法的优点在于它适用于任何具有
isEmpty()
方法的类!不仅仅是
收藏

例如,它也可以处理
字符串

/* Matches any class that has an <code>isEmpty()</code> method
 * that returns a <code>boolean</code> */ 
public class IsEmpty<T> extends TypeSafeMatcher<T>
{
    @Factory
    public static <T> Matcher<T> empty()
    {
        return new IsEmpty<T>();
    }

    @Override
    protected boolean matchesSafely(@Nonnull final T item)
    {
        try { return (boolean) item.getClass().getMethod("isEmpty", (Class<?>[]) null).invoke(item); }
        catch (final NoSuchMethodException e) { return false; }
        catch (final InvocationTargetException | IllegalAccessException e) { throw new RuntimeException(e); }
    }

    @Override
    public void describeTo(@Nonnull final Description description) { description.appendText("is empty"); }
}
这项工作:

assertThat(list,IsEmptyCollection.empty())

我发现如果你改变语法突出显示使括号不可见,Hamcrest代码看起来会更好…@tkeE2036:这就是Hamcrest在工作中破坏的泛型。有时您需要强制转换以使其编译,例如,
assertThat((集合)list,is(not(empty()))@dzieciou当测试失败时,它会为您提供更好的错误消息。因此,如果您不喜欢未经检查的转换,并且愿意放弃静态导入,则可以将泛型添加到方法中,例如:
assertThat(list,Matchers.empty())
(假设列表是
字符串的集合)@伊恩:这个答案已经过时,现在应该接受更好的答案。要获得更好的解决方案,请投票支持:@FabricioLemos issue#97似乎已经解决并合并到master git branch。希望它能很快在下一个hamcrest版本中发布。@rafalmag很好。当v1.3发布时,修复我所有不太可读的断言会很好sedIt很高兴看到假定为空的列表中还剩下什么!@rogerdpack给你。我添加了1.3样式的示例::)注意
assertThat(list,而不是(hasSize(0))
如果
list
null
,则
将成功,而不是
assertThat(list,hasSize(大于(0))
java.lang.AssertionError
Expected :[]
Actual   :[foo, bar]
/* Matches any class that has an <code>isEmpty()</code> method
 * that returns a <code>boolean</code> */ 
public class IsEmpty<T> extends TypeSafeMatcher<T>
{
    @Factory
    public static <T> Matcher<T> empty()
    {
        return new IsEmpty<T>();
    }

    @Override
    protected boolean matchesSafely(@Nonnull final T item)
    {
        try { return (boolean) item.getClass().getMethod("isEmpty", (Class<?>[]) null).invoke(item); }
        catch (final NoSuchMethodException e) { return false; }
        catch (final InvocationTargetException | IllegalAccessException e) { throw new RuntimeException(e); }
    }

    @Override
    public void describeTo(@Nonnull final Description description) { description.appendText("is empty"); }
}
assertThat(list,IsEmptyCollection.empty())