2013-08-28 7 views
7

Ich möchte überprüfen, ob eine Auflistung mindestens ein Nicht-Null-Element enthält. Ich habe versucht is(not(empty())), aber dies geht in dem Test weiter unten.Aktivieren Sie diese Auflistung "Enthält mindestens ein Nicht-Null-Element"

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

Gibt es eine elegante/einfache Möglichkeit, dies zu tun?

Dinge, die nicht

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

Antwort

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

... 

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

Leider gibt es ein bug in Java 1.6 das bedeutet, Sie könnten es auf zwei Zeilen aufgeteilt haben, wie here beschrieben, wenn Sie 1.6 verwenden:

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

EDIT Hier ist die FEST Assert Beispiel, nach dem Sie gefragt haben:

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

FEST erfordert nur einen einzigen statischen Import, damit Sie die vollständige IDE-Autovervollständigung erhalten.

0

dort arbeiten Sie ist keine einfache Art und Weise. Sie müssen die Elemente überprüfen, bis Sie eine gefunden haben, die nicht null ist.

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

Warum der Downvote? –

+0

sieht jetzt gut aus, obwohl Sie das erste 'if' nicht brauchen. Der Downvote ist nicht von mir. –

1

Sie können versuchen, die folgenden:

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

Als AJB bemerkt, wenn Sie Ihre Array unmodifizierten nach links wollen, sollten Sie einen Iterator und prüfen Sie jedes Element bis zum Ende der Sammlung oder ein verwenden nicht null eins.

+0

Der Punkt ist zu prüfen, ob es 'null' Elemente hat. Sie sollten sie nicht entfernen. –

+1

Der Punkt ist "zu überprüfen, dass eine Sammlung mindestens ein Nicht-Null-Element enthält." – Julien

+1

Sie könnten dies tun, ohne die 'null'-Elemente zu entfernen, indem Sie eine Kopie der Sammlung erstellen (eine temporäre Sammlung' c 'deklarieren und 'c.addAll' verwenden). Aber für diese Menge an Arbeit können Sie auch einfach einen Iterator verwenden. – ajb

1

Ich lief gerade in das gleiche Problem und löste es wie folgt.

Die Grundidee ist, dass, wenn die Sammlung nur null Elemente enthält, in ein Set konvertiert wird, enthält es nur ein Element und es wird null sein. Wenn nicht, dann enthält die Sammlung mindestens ein Nicht-Null-Element.

Ich schrieb einen Matcher, und versuchte es mit diesem 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(); 
    } 
} 

Natürlich in einem realen Projekt sollte die Matcher zusammen mit seinen Brüdern platziert werden :)

Hoffe, es hilft.

+0

Nizza, ein wiederverwendbarer Matcher. –