有没有一个 Hamcrest matcher 可以检查一个 Collection 既不为空也不为 null?

20

有没有一个 Hamcrest 匹配器可以检查参数既不是空集合也不是 null?

我猜我总是可以使用

both(notNullValue()).and(not(hasSize(0))

但我在想是否有更简单的方法,而我错过了它。


3
我认为这看起来相当简单。此外,重要的是您的测试尽可能清晰地表达其意图,并且代码非常易读。 - skaffman
我其实不太了解 hamcrest,但从逻辑上讲,如果 API 支持此类调用,您可以检查 size >= 0 - mike
1
这个问题的标题与正文相反。回答问题的标题:assertThat( metadata, either( is( empty() ) ).or( is( nullValue() ) ) ); - Abdull
不是与您的问题完全匹配,但是您可以使用assertTrue(CollectionUtils.isNotEmpty(collectioin))CollectionUtils是Apache Commons Lang类。 - DwB
3个回答

13

你可以将 IsCollectionWithSizeOrderingComparison 匹配器结合起来使用:

@Test
public void test() throws Exception {
    Collection<String> collection = ...;
    assertThat(collection, hasSize(greaterThan(0)));
}
  • collection = null 时,您会得到

    java.lang.AssertionError: 
    Expected: a collection with size a value greater than <0>
        but: was null
    
  • 如果使用collection = Collections.emptyList(),你将得到

  • java.lang.AssertionError: 
    Expected: a collection with size a value greater than <0>
        but: collection size <0> was equal to <0>
    
  • 对于collection = Collections.singletonList("Hello world"),测试通过。

编辑:

刚刚注意到下面的方法不起作用

assertThat(collection, is(not(empty())));

我越想越觉得,如果您想显式地测试 null,则建议略微修改 OP 所写的陈述。

assertThat(collection, both(not(empty())).and(notNullValue()));

我接受了你的答案,因为我认为这里展示的两种方式 hasSize(greaterThan(0))both(not(empty())).and(notNullValue()) 都是不错的方法。 - jhyot
当我使用你的代码检查空集合或null时,为什么会出现"1 expectation failed. JSON path images doesn't match. Expected: (an empty collection or null) Actual: null"的错误提示?代码如下: myResponse.body(myArrayAttr, either(empty()).or(nullValue())); - TheBakker

2
你可以使用匹配器(Matchers):最初的回答。
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.anyOf;

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

2

如我在评论中提到的那样,collection != nullsize != 0的逻辑等价于size > 0,这意味着集合不为null。表达size > 0的更简单的方法是集合中存在(任意)元素X。以下是一个可行的代码示例。

import static org.hamcrest.core.IsCollectionContaining.hasItem;
import static org.hamcrest.CoreMatchers.anything;

public class Main {

    public static void main(String[] args) {
        boolean result = hasItem(anything()).matches(null);
        System.out.println(result); // false for null

        result = hasItem(anything()).matches(Arrays.asList());
        System.out.println(result); // false for empty

        result = hasItem(anything()).matches(Arrays.asList(1, 2));
        System.out.println(result); // true for (non-null and) non-empty 
    }
}

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