2013-08-28 18 views
7

Desidero verificare che una raccolta contenga almeno un elemento non null. Ho provato is(not(empty())), tuttavia questo passaggio nel test di seguito.Asserire che la raccolta "Contiene almeno un elemento non null"

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()))); 
    } 
} 

C'è un modo elegante/semplice per farlo?

cose che non funzionano

@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) 

risposta

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

... 

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

Purtroppo, c'è un bug in Java 1.6 che significa che potrebbe essere necessario dividere su 2 linee come descritto here se si utilizza 1.6:

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

EDIT Ecco il FEST Assert esempio che hai richiesto:

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

FEST richiede solo una singola importazione statica in modo da ottenere il completamento automatico completo IDE.

0

Non v'è alcun modo semplice. Devi controllare gli elementi finché non ne trovi uno che non sia nullo.

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

Perché il downvote? –

+0

sembra buono ora, anche se non è necessario il primo 'se'. Il downvote non è da parte mia. –

1

Si può provare la seguente:

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()))); 
    } 

Come AJB avvisi, se si vuole sinistra l'array non modificato, è necessario utilizzare un iteratore e verificare ogni elemento fino alla fine della raccolta o di un non nullo.

+0

Il punto è controllare se ha elementi 'null'. Non dovresti rimuoverli. –

+1

Il punto è "per verificare che una raccolta contenga almeno un elemento non nullo." – Julien

+1

Si può fare questo lavoro senza rimuovere gli elementi 'null' creando una copia della collezione (dichiarare una collezione temporanea' c' e usare 'c.addAll'). Ma per quella quantità di lavoro, puoi anche usare un iteratore. – ajb

1

Mi sono imbattuto nello stesso problema e l'ho risolto come segue.

L'idea di base è che se la raccolta contiene solo elementi null, convertiti in un set conterrà solo un elemento e sarà null. In caso contrario, la raccolta contiene almeno un elemento non null.

ho scritto un matcher, e l'ho provato con questo test:

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(); 
    } 
} 

Naturalmente, in un vero e proprio progetto, il matcher deve essere posto insieme ai suoi fratelli :)

Speranza che aiuta.

+0

Nice, un matcher riutilizzabile. –

Problemi correlati