检查集合是否为空或为null的标准Hamcrest匹配器?

9

是否有使用标准Hamcrest匹配器的更短版本的assert语句?

Collection<Element> collection = ...

assertThat(collection, is(anyOf(nullValue(Collection.class), 
     emptyCollectionOf(Element.class))));

我知道可以创建自定义匹配器,但希望能有现成的解决方案,而不需要进行任何额外的代码更改。


如果您的代码更改为不返回null而是返回空集合,则有一个更短的版本。 - M. Prokhorov
4个回答

12

没有现成的解决方案,更糟糕的是,either()由于缺陷无法使用。因此,最简单的方式是:

assertThat(collection, anyOf(nullValue(), empty()));

2

实现这个的一种方法是创建一个自定义的Hamcrest匹配器,它结合了已经可用的匹配(例如IsNull.nullValue()IsEmptyCollection.empty())。

但一般来说,一个断言应该只断言一件事情。 我的意见是,在连续使用两个匹配器时,这并不会带来太大的痛苦,并且后期更易读。

此外,还有另一种首选模式——在返回集合时,优先返回空集合而不是null。其想法是避免不必要的null检查。


我原则上同意你的第二个陈述。但实际上,这种组合情况经常出现,因此最好有类似emptyOrNull()这样的东西。 - Altair7852
不同的方法都是可行的-您可以始终创建一个自定义匹配器(正如其他答案中建议的那样),或者只需将这两个断言包装在一个实用程序方法“nullOrEmpty(testTarget)”中,并在所有需要的地方调用它。最终,这只是测试用例-如果它测试了预期的功能-就可以继续进行。我真的看不出将这两行代码压缩成一条断言会有多大好处。 - hovanessyan

1
我能想到的唯一方法是编写自己的Matcher。
class EmptyOrNull extends BaseMatcher<Collection> {
    public boolean matches(Object o) {
        boolean result = o == null;
        if (o instanceof Collection) {
            result = ((Collection) o).isEmpty();
        }
        return result;
    }
    public String describeMismatch(Object item, Description description) {
        return "not null or empty!";
    }
    public static Matcher<Collection> emptyOrNull() { return new EmptyOrNull(); }
}

然后你可以使用较短的版本。保留HTML。
assertThat(collection, emptyOrNull());

0
考虑使用 Assert.fail 的简单命令式解决方案。
if (collection != null && !collection.isEmpty()) {
    fail(collection.toString());
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接