检查列表在 Hamcrest 是否为空

我想知道是否有人知道如何使用 assertThat()Matchers检查 List 是否为空?

我认为使用 JUnit 的最佳方式是:

assertFalse(list.isEmpty());

但我希望在 Hamcrest 能有办法做到这一点。

135445 次浏览

总会有的

assertThat(list.isEmpty(), is(false));

... 但我猜你不是这个意思:)

或者:

assertThat((Collection)list, is(not(empty())));

empty()Matchers类中的静态。请注意,由于 Hamcrest 1.2的不稳定的仿制品,需要将 list转换为 Collection

下面的导入可以与 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())));

但是,如果你不得不使用旧版本-而不是错误的 empty(),你可以使用:

hasSize(greaterThan(0))
(import static org.hamcrest.number.OrderingComparison.greaterThan;
import static org.hamcrest.Matchers.greaterThan;)

例如:

// given
List<String> list = new ArrayList<String>();
// then
assertThat(list, hasSize(greaterThan(0)));

关于上述解决方案,最重要的是它不生成任何警告。 如果您想估计最小结果大小,第二种解决方案甚至更有用。

如果你在寻找可读的失败消息,你可以不使用 hamcrest,使用通常的 assertEquals 和一个空列表:

assertEquals(new ArrayList<>(0), yourList);

例如,如果你逃跑

assertEquals(new ArrayList<>(0), Arrays.asList("foo", "bar");

你得到了

java.lang.AssertionError
Expected :[]
Actual   :[foo, bar]

创建自定义 IsEmpty TypeSafeMatcher:

即使泛型问题在 1.3中得到解决,这个方法的伟大之处在于它适用于任何具有 isEmpty()方法的类!不只是 Collections

例如,它将工作在 String以及!

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