7

我想验证一个集合是否至少包含一个非空元素。我试过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)
4

4 回答 4

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

...

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

不幸的是, Java 1.6中存在一个错误,意味着如果您使用 1.6 ,您可能必须将其拆分为 2 行,如下所述:

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 自动完成。

于 2013-08-28T21:01:10.913 回答
2

我刚刚遇到了同样的问题并解决了如下。

基本思想是,如果集合只有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();
    }
}

当然,在实际项目中,匹配器应该和它的兄弟放在一起:)

希望能帮助到你。

于 2014-03-15T22:29:56.157 回答
1

你在正确的轨道上,链接Matcher实例。你只需要hasItem匹配器(就像我在这里建议的那样)而不是contains.

为 s 创建一个匹配器,该匹配器Iterable仅在单次通过检查Iterable产生至少一个与指定 匹配的项目时匹配itemMatcherIterable在匹配时,一旦找到匹配项,检查对象的遍历就会停止。

例如,

Collection<Integer> collection = new ArrayList<Integer>();
collection.add(null);

assertThat(collection, hasItem(is(not(nullValue()))));

将失败

java.lang.AssertionError: 
Expected: a collection containing is not null
     but: was null
    at org.hamcrest.MatcherAssert.assertThat(MatcherAssert.java:20)
    at org.hamcrest.MatcherAssert.assertThat(MatcherAssert.java:8)
    at com.example.ExampleTest.should(ExampleTest.java:21)
    at [...]

然而

Collection<Integer> collection = new ArrayList<Integer>();
collection.add(null);
collection.add("hey");
collection.add(null);

assertThat(collection, hasItem(is(not(nullValue()))));
// or shortened
assertThat(collection, hasItem(notNullValue()));

将会成功。

于 2013-08-28T20:28:27.537 回答
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 所指出的,如果您想保持数组不变,您应该使用迭代器并检查每个元素,直到集合结束或非空元素。

于 2013-08-28T20:30:32.890 回答