我想验证集合是否包含至少一个非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)
答案 0 :(得分:6)
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.*;
...
assertThat(collection, hasItem(notNullValue(Integer.class)));
不幸的是,有一个bug in Java 1.6表示如果您使用1.6,则可能需要将其分为2行,如here所述:
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自动完成功能。
答案 1 :(得分:2)
我遇到了同样的问题并解决了如下问题。
基本思想是,如果集合只有null
元素,转换为集合,它将只包含一个元素,它将是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();
}
}
当然,在一个真实的项目中,匹配器应该与其兄弟放在一起:)
希望它有所帮助。
答案 2 :(得分: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通知,如果你想不修改你的数组,你应该使用迭代器并检查每个元素直到集合的结尾或非空元素。
答案 3 :(得分:0)
没有简单的方法。你必须检查元素,直到找到一个不为空的元素。
public boolean hasAtLeastOneNotNull(Collection<?> collection) {
Iterator<?> it = collection.iterator();
while(it.hasNext()) {
if (it.next() != null)
return true;
}
return false;
}