Comprobando que una Lista no está vacía en Hamcrest

147

Me preguntaba si alguien sabía de una manera de verificar si una Lista está vacía usando assertThat()y Matchers?

La mejor manera que pude ver es usar JUnit:

assertFalse(list.isEmpty());

Pero esperaba que hubiera alguna forma de hacer esto en Hamcrest.

Ian Dallas
fuente
2
Para una mejor solución, vote por: code.google.com/p/hamcrest/issues/detail?id=97
Fabricio Lemos
2
El problema # 97 de @FabricioLemos parece estar resuelto y se fusiona para dominar git branch. Esperemos que sea pronto en el próximo lanzamiento de Hamcrest.
rafalmag
@rafalmag Buen lugar. Será bueno arreglar todas mis afirmaciones no tan legibles cuando se publique la v1.3
andyb

Respuestas:

165

Bueno siempre hay

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

... pero supongo que eso no es lo que querías decir :)

Alternativamente:

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

empty()Es una estática en la Matchersclase. Tenga en cuenta la necesidad de lanzar el listto Collection, gracias a los genéricos inestables de Hamcrest 1.2.

Las siguientes importaciones se pueden utilizar con Hamcrest 1.3

import static org.hamcrest.Matchers.empty;
import static org.hamcrest.core.Is.is;
import static org.hamcrest.core.IsNot.*;
skaffman
fuente
66
Me parece que el código Hamcrest parece mucho más agradable si cambia de resaltado de sintaxis para hacer el paréntesis invisible ...
skaffman
2
@ tkeE2036: Son los genéricos rotos de Hamcrest en el trabajo. A veces necesitas emitir para compilarlo, por ejemploassertThat((Collection)list, is(not(empty())));
skaffman
77
Este se fija en 1,3
artbristol
14
@dzieciou te da un mejor mensaje de error cuando falla la prueba. Entonces, en lugar de expected true but got falseobtener algo comoexpected empty but got [1, 2, 3]
Brad Cupit
3
Si prefiere no realizar una conversión sin control y está dispuesto a renunciar a la importación estática, puede agregar los genéricos al método, como: assertThat(list, Matchers.<String>empty())(suponiendo que la lista sea una colección de Strings)
earcam
77

Esto se soluciona en Hamcrest 1.3. El siguiente código compila y no genera ninguna advertencia:

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

Pero si tiene que usar una versión anterior, en lugar de tener errores empty(), puede usar:

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

Ejemplo:

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

Lo más importante sobre las soluciones anteriores es que no genera ninguna advertencia. La segunda solución es aún más útil si desea estimar el tamaño mínimo del resultado.

rafalmag
fuente
1
@rogerdpack Aquí tienes. Agregué el ejemplo de estilo 1.3. :)
rafalmag
1
Tenga en cuenta que assertThat(list, not(hasSize(0)))será exitoso si listes null, a diferencia deassertThat(list, hasSize(greaterThan(0)))
José Andias
5

Si buscas mensajes de error legibles, puedes prescindir de los inconvenientes utilizando los aserciones iguales habituales con una lista vacía:

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

Por ejemplo, si corres

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

usted obtiene

java.lang.AssertionError
Expected :[]
Actual   :[foo, bar]
kamczak
fuente
2
¡Es realmente agradable ver lo que quedó en la lista supuestamente vacía!
HDave
0

Cree su propio IsEmpty TypeSafeMatcher personalizado:

Incluso si los problemas genéricos se solucionan, 1.3lo mejor de este método es que funciona en cualquier clase que tenga un isEmpty()método. No sólo Collections!

Por ejemplo, ¡funcionará Stringtambién!

/* 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"); }
}
Comunidad
fuente
0

Esto funciona:

assertThat(list,IsEmptyCollection.empty())
Ricardo
fuente