2013-08-28 57 views
7

Tôi muốn xác minh rằng bộ sưu tập có chứa ít nhất một phần tử không null. Tôi đã thử is(not(empty())), tuy nhiên điều này vượt qua trong bài kiểm tra dưới đây.Xác nhận rằng bộ sưu tập "Chứa ít nhất một phần tử không null"

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

Có cách nào đơn giản/thanh lịch để thực hiện việc này không?

Những điều đó không làm việc

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

Trả lời

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

... 

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

Thật không may, có một bug in Java 1.6 đó có nghĩa là bạn có thể phải chia nó vào 2 dòng như mô tả here nếu bạn đang sử dụng 1.6:

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

EDIT Đây là FEST Assert ví dụ bạn đã yêu cầu:

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

FEST chỉ yêu cầu một lần nhập tĩnh duy nhất để bạn hoàn thành tự động hoàn thành IDE.

0

Không có cách nào đơn giản. Bạn phải kiểm tra các yếu tố cho đến khi bạn tìm thấy một phần tử không phải là rỗng.

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

Tại sao lưu ý lại? –

+0

có vẻ tốt ngay bây giờ, mặc dù bạn không cần 'if' đầu tiên. Downvote không phải từ tôi. –

1

Bạn có thể thử như sau:

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

Như AJB thông báo, nếu bạn muốn để lại mảng của bạn chưa sửa đổi, bạn nên sử dụng một iterator và kiểm tra từng yếu tố cho đến cuối của bộ sưu tập hoặc một không một.

+0

Vấn đề là kiểm tra xem nó có các phần tử 'null' hay không. Bạn không nên xóa chúng. –

+1

Vấn đề là "để xác minh rằng tập hợp chứa ít nhất một phần tử không null". – Julien

+1

Bạn có thể thực hiện công việc này mà không xóa các phần tử 'null' bằng cách tạo một bản sao của bộ sưu tập (khai báo một bộ sưu tập tạm thời' c' và sử dụng 'c.addAll'). Nhưng với số lượng công việc đó, bạn cũng có thể sử dụng một trình lặp. – ajb

1

Tôi vừa gặp sự cố tương tự và đã giải quyết vấn đề như sau.

Ý tưởng cơ bản là nếu bộ sưu tập chỉ có các thành phần null, được chuyển đổi thành bộ, nó sẽ chỉ chứa một phần tử và nó sẽ là null. Nếu không, thì tập hợp chứa ít nhất một phần tử không null.

tôi đã viết một khớp, và thử nó với thử nghiệm này:

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

Tất nhiên, trong một dự án thực tế, các khớp nên được đặt cùng với anh em của nó :)

Hy vọng nó giúp.

+0

Tốt đẹp, một trình kết hợp lại có thể tái sử dụng. –