2013-08-28 142 views
7

我想驗證集合是否至少包含一個非null元素。我試過is(not(empty())),但是這在下面的測試中通過。斷言集合「至少包含一個非空元素」

import org.junit.Test; 

import java.util.ArrayList; 
import java.util.Collection; 

import static org.hamcrest.CoreMatchers.is; 
import static org.hamcrest.MatcherAssert.assertThat; 
import static org.hamcrest.Matchers.empty; 
import static org.hamcrest.Matchers.not; 

public class SandBoxTest { 
    @Test 
    public void shouldTestThis() { 
     Collection<Integer> collection = new ArrayList<Integer>(); 
     collection.add(null); 

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

有沒有一個優雅/簡單的方法來做到這一點?

事情,不工作

@Test 
public void should(){ 
    Collection<String> collection = new ArrayList(); 
    collection.add("gfas"); 
    collection.add("asda"); 
    assertThat(collection, contains(notNullValue())); 
} 

java.lang.AssertionError: 
Expected: iterable containing [not null] 
    but: Not matched: "asda" 
at org.hamcrest.MatcherAssert.assertThat(MatcherAssert.java:20) 

回答

6
import static org.hamcrest.MatcherAssert.assertThat; 
import static org.hamcrest.Matchers.*; 

... 

assertThat(collection, hasItem(notNullValue(Integer.class))); 

不幸的是,有一個bug in Java 1.6這意味着你可能必須將其分割到2線描述here如果你正在使用1.6:

Matcher<Iterable<? super String>> matcher = hasItem(notNullValue(Integer.class)); 
assertThat(collection, matcher); 

編輯這裏是FEST Assert您要求的示例:

import static org.fest.assertions.api.Assertions.assertThat; 
... 
assertThat(collection).doesNotContainNull(); 

FEST只需要一個靜態導入,因此您可以獲得完整的IDE自動完成。

0

有沒有簡單的方法。您必須檢查元素,直到找到不爲空的元素。

public boolean hasAtLeastOneNotNull(Collection<?> collection) { 
    Iterator<?> it = collection.iterator(); 
    while(it.hasNext()) { 
     if (it.next() != null) 
      return true; 
    } 
    return false; 
} 
+1

爲什麼downvote? –

+0

現在看起來不錯,雖然你不需要第一個「if」。 downvote不是從我。 –

1

你可以嘗試以下方法:

public void shouldTestThis() { 
     Collection<Integer> collection = new ArrayList<Integer>(); 
     collection.add(null); 
     collection.removeAll(Collections.singleton(null)); // remove all "null" elements from collection 
     assertThat(collection, is(not(empty()))); 
    } 

由於AJB通知,如果你想離開你的數組不被修改,應使用一個迭代和檢查每個元素,直到集合或結束非空一個。

+0

重點是檢查它是否有'null'元素。你不應該刪除它們。 –

+1

重點是「驗證一個集合包含至少一個非空元素。」 – Julien

+1

您可以通過製作集合的副本(聲明臨時集合'c'並使用'c.addAll')來完成這項工作,而無需刪除'null'元素。但是對於這些工作量,你可能只是使用迭代器。 – ajb

1

我剛碰到相同的問題,並解決它如下。

基本思想是,如果集合只有null元素,轉換爲集合,它將只包含一個元素,它將是null。如果不是這樣,那麼集合至少包含一個非空元素。

我寫了一個匹配,並與該測試試了一下:

import org.hamcrest.Description; 
import org.hamcrest.Factory; 
import org.hamcrest.Matcher; 
import org.hamcrest.TypeSafeMatcher; 
import org.junit.Test; 

import java.util.ArrayList; 
import java.util.Collection; 
import java.util.HashSet; 
import java.util.Set; 

import static org.hamcrest.CoreMatchers.is; 
import static org.hamcrest.CoreMatchers.not; 
import static org.junit.Assert.assertThat; 
import static personal.CollectionOfNullsMatcher.collectionOfNulls; 


public class SimpleTest { 

    @Test 
    public void should_check_collection_for_non_null_values() { 
     Collection<String> testedCollection = new ArrayList<String>(); 
     testedCollection.add(null); 

     assertThat(testedCollection, is(collectionOfNulls())); 

     testedCollection.add("any"); 

     assertThat(testedCollection, is(not(collectionOfNulls()))); 
    } 
} 

class CollectionOfNullsMatcher extends TypeSafeMatcher<Collection> { 

    @Override 
    protected boolean matchesSafely(final Collection collection) { 
     Set<Object> set = new HashSet<Object>(collection); 
     return (set.size() == 1) && (set.toArray()[0] == null); 
    } 

    @Override 
    public void describeTo(final Description description) { 
     description.appendText("collection of nulls"); 
    } 

    @Factory 
    public static <T> Matcher<Collection> collectionOfNulls() { 
     return new CollectionOfNullsMatcher(); 
    } 
} 

當然,在實際項目中,匹配應連同其兄弟:)

希望它可以幫助安置。

+0

尼斯,可重複使用的匹配器。 –

相關問題