Проверка того, что список не пуст в Hamcrest

Мне было интересно узнать, знает ли кто-нибудь, проверить ли List пустым с помощью assertThat() и Matchers?

Лучший способ, которым я мог видеть, просто использовать JUnit:

assertFalse(list.isEmpty());

Но я надеялся, что в Hamcrest есть способ сделать это.

Ответ 1

Хорошо, всегда

assertThat(list.isEmpty(), is(false));

... но я предполагаю, что не совсем то, что вы имели в виду:)

В качестве альтернативы:

assertThat((Collection)list, is(not(empty())));

empty() является статичным в классе Matchers. Обратите внимание на необходимость отбрасывания list до Collection, благодаря генерирующим генераторам Hamcrest 1.2.

Следующие импорта могут использоваться с hamcrest 1.3

import static org.hamcrest.Matchers.empty;
import static org.hamcrest.core.Is.is;
import static org.hamcrest.core.IsNot.*;

Ответ 2

Это зафиксировано в Hamcrest 1.3. Следующий код компилирует и не генерирует никаких предупреждений:

// given
List<String> list = new ArrayList<String>();
// then
assertThat(list, is(not(empty())));

Но если вам нужно использовать более старую версию - вместо прослушивания empty() вы можете использовать:

hasSize(greaterThan(0))
(import static org.hamcrest.number.OrderingComparison.greaterThan; или
import static org.hamcrest.Matchers.greaterThan;)

Пример:

// given
List<String> list = new ArrayList<String>();
// then
assertThat(list, hasSize(greaterThan(0)));

Самое главное в вышеупомянутых решениях состоит в том, что он не генерирует никаких предупреждений. Второе решение еще более полезно, если вы хотите оценить минимальный размер результата.

Ответ 3

Если вы читаете сообщения об ошибках, вы можете обойтись без hamcrest, используя обычные assertEquals с пустым списком:

assertEquals(new ArrayList<>(0), yourList);

например. если вы запустите

assertEquals(new ArrayList<>(0), Arrays.asList("foo", "bar");

вы получаете

java.lang.AssertionError
Expected :[]
Actual   :[foo, bar]

Ответ 4

Создайте свой собственный ISEmpty TypeSafeMatcher:

Даже если проблемы с дженериками фиксированы в 1.3, великая вещь в этом методе заключается в том, что он работает над любым классом, который имеет метод isEmpty()! Не только Collections!

Например, он будет работать и на String!

/* Matches any class that has an <code>isEmpty()</code> method
 * that returns a <code>boolean</code> */ 
public class IsEmpty<T> extends TypeSafeMatcher<T>
{
    @Factory
    public static <T> Matcher<T> empty()
    {
        return new IsEmpty<T>();
    }

    @Override
    protected boolean matchesSafely(@Nonnull final T item)
    {
        try { return (boolean) item.getClass().getMethod("isEmpty", (Class<?>[]) null).invoke(item); }
        catch (final NoSuchMethodException e) { return false; }
        catch (final InvocationTargetException | IllegalAccessException e) { throw new RuntimeException(e); }
    }

    @Override
    public void describeTo(@Nonnull final Description description) { description.appendText("is empty"); }
}