7

コレクションに少なくとも 1 つの非 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)
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要素しかない場合、セットに変換すると、要素が 1 つだけ含まれ、null. そうでない場合、コレクションには少なくとも 1 つの非 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

検査対象の 1 回のパスで、指定された に一致するアイテムが少なくとも 1 つ生成さIterableれる場合にのみ一致する s のマッチャーを作成します。照合中、一致するアイテムが見つかるとすぐに、調査対象のトラバーサルが停止します。IterableitemMatcherIterable

例えば、

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 が気づいたように、配列を変更せずに残したい場合は、イテレータを使用して、コレクションの最後まで、または null 以外の要素まで各要素をチェックする必要があります。

于 2013-08-28T20:30:32.890 に答える