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

147

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

Лучший способ увидеть это - использовать JUnit:

assertFalse(list.isEmpty());

Но я надеялся, что есть какой-то способ сделать это в Хэмкресте.

Ян Даллас
источник
2
Чтобы найти лучшее решение, проголосуйте за: code.google.com/p/hamcrest/issues/detail?id=97
Fabricio Lemos,
2
Проблема @FabricioLemos # 97, похоже, решена и добавлена ​​в основную ветку git. Будем надеяться, что это скоро будет в следующем выпуске Hamcrest.
Рафальмаг
@rafalmag Хорошее место. Будет хорошо исправить все мои не очень читаемые утверждения, когда выйдет v1.3
andyb

Ответы:

165

Ну всегда есть

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.*;
skaffman
источник
6
Я считаю, что код Hamcrest выглядит намного лучше, если вы измените подсветку синтаксиса, чтобы сделать скобки невидимыми ...
skaffman
2
@ tkeE2036: Это сломанные дженерики Хамкреста на работе. Иногда вам нужно выполнить приведение к компиляции, напримерassertThat((Collection)list, is(not(empty())));
skaffman
7
Это исправлено в 1.3
artbristol
14
@dzieciou дает вам лучшее сообщение об ошибке, когда тест не пройден. Так что вместо expected true but got falseтебя получается что-то вродеexpected empty but got [1, 2, 3]
Брэд Купит
3
Если вы не предпочитаете неконтролируемое преобразование и хотите отказаться от статического импорта, вы можете добавить к этому методу assertThat(list, Matchers.<String>empty())String
обобщенные значения
77

Это исправлено в 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)));

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

rafalmag
источник
1
@rogerdpack Вот, пожалуйста. Я добавил пример стиля 1.3. :)
rafalmag
1
Остерегайтесь, что assertThat(list, not(hasSize(0)))будет успешным, если listесть null, в отличие отassertThat(list, hasSize(greaterThan(0)))
Хосе Андиас
5

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

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

Например, если вы бежите

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

ты получаешь

java.lang.AssertionError
Expected :[]
Actual   :[foo, bar]
kamczak
источник
2
Очень приятно видеть, что осталось в якобы пустом списке!
HDave
0

Создайте свой собственный 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"); }
}
Сообщество
источник
0

Это работает:

assertThat(list,IsEmptyCollection.empty())
Ричард
источник