Verificando se uma lista não está vazia no Hamcrest

147

Eu queria saber se alguém sabia uma maneira de verificar se uma lista está vazia usando assertThat()e Matchers?

A melhor maneira que pude ver, basta usar o JUnit:

assertFalse(list.isEmpty());

Mas eu esperava que houvesse alguma maneira de fazer isso em Hamcrest.

Ian Dallas
fonte
2
Para uma solução melhor, vote em: code.google.com/p/hamcrest/issues/detail?id=97
Fabricio Lemos
2
O problema do @FabricioLemos # 97 parece ter sido resolvido e mesclado para o master git branch. Vamos esperar que seja em breve no próximo lançamento de hamcrest.
Rafalmag 13/05/12
@rafalmag Bom local. Será bom para corrigir todas as minhas afirmações não tão legíveis quando v1.3 é liberada
andyb

Respostas:

165

Bem, há sempre

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

... mas acho que não foi exatamente isso que você quis dizer :)

Alternativamente:

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

empty()é uma estática na Matchersclasse. Note-se a necessidade de lançar o listque Collection, graças a Hamcrest 1,2 de genéricos vacilante.

As seguintes importações podem ser usadas com o hamcrest 1.3

import static org.hamcrest.Matchers.empty;
import static org.hamcrest.core.Is.is;
import static org.hamcrest.core.IsNot.*;
skaffman
fonte
6
Eu acho que o código Hamcrest uma melhor aparência se você mudar de destaque de sintaxe para fazer o parêntese invisível ...
skaffman
2
@ tkeE2036: São os genéricos quebrados de Hamcrest no trabalho. Às vezes você precisa converter para compilá-lo, por exemploassertThat((Collection)list, is(not(empty())));
skaffman
7
Isso é corrigido no 1.3
artbristol 17/08/2012
14
@dzieciou, fornece uma mensagem de erro melhor quando o teste falha. Então, em vez de expected true but got falseobter algo comoexpected empty but got [1, 2, 3]
Brad Cupit 22/10/12
3
Se preferir nenhuma conversão for controlada, e estão dispostos a dar-se a importação estática, então você pode adicionar os genéricos para o método, como: assertThat(list, Matchers.<String>empty())(lista assumindo é uma coleção de Strings)
earcam
77

Isso é corrigido no Hamcrest 1.3. O código abaixo compila e não gera nenhum aviso:

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

Mas se você tiver que usar uma versão mais antiga - em vez de com bug, empty()poderá usar:

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

Exemplo:

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

O mais importante das soluções acima é que elas não geram avisos. A segunda solução é ainda mais útil se você deseja estimar o tamanho mínimo do resultado.

rafalmag
fonte
1
@rogerdpack Aqui você vai. Eu adicionei o exemplo do estilo 1.3. :)
rafalmag
1
Cuidado com o que assertThat(list, not(hasSize(0)))será bem sucedido se listfor null, em oposição aassertThat(list, hasSize(greaterThan(0)))
José Andias 12/08
5

Se você estiver atrás de mensagens de falha legíveis, poderá ficar sem interrupção usando o assertEquals usual com uma lista vazia:

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

Por exemplo, se você executar

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

você recebe

java.lang.AssertionError
Expected :[]
Actual   :[foo, bar]
kamczak
fonte
2
É realmente bom ver o que foi deixado na lista supostamente vazia!
HDave
0

Crie seu próprio IsEmpty TypeSafeMatcher personalizado:

Mesmo que os problemas genéricos sejam corrigidos de maneira 1.3ótima sobre esse método, ele funciona em qualquer classe que possua um isEmpty()método! Não é só Collections!

Por exemplo, ele funcionará Stringtambém!

/* 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"); }
}
Comunidade
fonte
0

Isso funciona:

assertThat(list,IsEmptyCollection.empty())
Richard
fonte