Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Assert that collection "Contains at least one non-null element"

I want to verify that a collection contains at least one non-null element. I have tried is(not(empty())), however this passes in the test below.

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

Is there an elegant/simple way to do this?

Things That Don't Work

@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)
like image 536
Mike Rylander Avatar asked Aug 28 '13 20:08

Mike Rylander


People also ask

Which assertion is used to check whether object is null?

void assertNull(Object object) Checks that an object is null.

Which method of Assert check that a string is empty?

The isEmpty() method checks whether a string is empty or not. This method returns true if the string is empty (length() is 0), and false if not.

How do you assert a null object?

Assert class in case of JUnit 4 or JUnit 3 to assert using assertNull method. Assertions. assertNull() checks that object is null. In case, object is not null, it will through AssertError.


2 Answers

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

...

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

Unfortunately, there is a bug in Java 1.6 that means you might have to split it onto 2 lines as described here if you are using 1.6:

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

EDIT Here is the FEST Assert example you asked for:

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

FEST requires only a single static import so you get full IDE auto completion.

like image 156
samlewis Avatar answered Sep 24 '22 07:09

samlewis


I just ran into the same problem and solved it as follows.

The basic idea is that if the collection has only null elements, converted to a set it will contain just one element and it will be null. If not so, then the collection contains at least one non-null element.

I wrote a matcher, and tried it with this 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();
    }
}

Of course, in a real project, the matcher should be placed together with its brothers :)

Hope it helps.

like image 44
Sergio Pelin Avatar answered Sep 21 '22 07:09

Sergio Pelin