¿Cómo usar JUnit y Hamcrest juntos?

88

No puedo entender cómo debería funcionar JUnit 4.8 con los comparadores Hamcrest. Hay algunos matchers definidos dentro junit-4.8.jarde org.hamcrest.CoreMatchers. Al mismo tiempo, hay otros comparadores hamcrest-all-1.1.jaren org.hamcrest.Matchers. Entonces, ¿adónde ir? ¿Debo incluir explícitamente hamcrest JAR en el proyecto e ignorar los emparejadores proporcionados por JUnit?

En particular, estoy interesado en el empty()emparejador y no puedo encontrarlo en ninguno de estos frascos. Necesito algo mas :)

Y una pregunta filosófica: ¿por qué JUnit incluyó el org.hamcrestpaquete en su propia distribución en lugar de alentarnos a usar la biblioteca original de Hamcrest?

yegor256
fuente

Respuestas:

49

junit proporciona nuevos métodos de verificación de aserción llamados assertThat () que usa Matchers y debería proporcionar un código de prueba más legible y mejores mensajes de falla.

Para usar esto, hay algunos comparadores principales incluidos en junit. Puede comenzar con estos para las pruebas básicas.

Si desea utilizar más comparadores, puede escribirlos usted mismo o utilizar la biblioteca hamcrest.

El siguiente ejemplo demuestra cómo usar el comparador vacío en una ArrayList:

package com.test;

import static org.hamcrest.Matchers.empty;
import static org.hamcrest.Matchers.is;
import static org.junit.Assert.assertThat;

import java.util.ArrayList;
import java.util.List;

import org.junit.Test;

public class EmptyTest {
    @Test
    public void testIsEmpty() {
        List myList = new ArrayList();
        assertThat(myList, is(empty()));

    }
}

(Incluí hamcrest-all.jar en mi ruta de construcción)

cpater
fuente
2
¿Dónde org.hamcrest.Matchers.empty()se encuentra exactamente ? ¿Podría dar un enlace al archivo JAR?
yegor256
Puede encontrar todo aquí: code.google.com/p/hamcrest y la descarga de hamcrest-all.jar aquí: code.google.com/p/hamcrest/downloads/…
cpater
1
Parece que hamcrest 1.2 no está en el repositorio de Maven Central. Ese es el problema al que me enfrento :(
yegor256
5
Hamcrest 1.3 ya ha sido lanzado y está en maven central.
Tom
50

Si está usando un Hamcrest con una versión mayor o igual a 1.2, entonces debe usar el junit-dep.jar. Este jar no tiene clases de Hamcrest y por lo tanto evita problemas de carga de clases.

Desde JUnit 4.11, el junit.jarmismo no tiene clases de Hamcrest. Ya no es necesario junit-dep.jar.

Stefan Birkner
fuente
2
Parece que a partir de JUnit 4.12, ya no hay junit-dep.jar. ¿Es ese el caso? Y si es así, ¿estamos destinados a utilizar el tarro Hamcrest 1.3 independiente?
Jeff Evans
1
Respuesta a ambas preguntas: sí.
Stefan Birkner
25

No responde exactamente a su pregunta, pero definitivamente debería probar la API de aserciones fluidas FEST-Assert . Está compitiendo con Hamcrest, pero tiene una API mucho más sencilla con solo una importación estática requerida. Aquí está el código proporcionado por cpater usando FEST:

package com.test;
import java.util.ArrayList;
import java.util.List;
import org.junit.Test;
import static org.fest.assertions.Assertions.assertThat;

public class EmptyTest {
    @Test
    public void testIsEmpty() {
        List myList = new ArrayList();
        assertThat(myList).isEmpty();
    }  
}

EDITAR: Coordenadas de Maven:

<dependency>
  <groupId>org.easytesting</groupId>
  <artifactId>fest-assert</artifactId>
  <version>1.4</version>
  <scope>test</scope>
</dependency>
Tomasz Nurkiewicz
fuente
3
Acabo de cambiar mi biblioteca de afirmaciones. Estaba bastante satisfecho con Hamcrest, pero debido a la inclusión problemática de junit y algunas pruebas difíciles de escribir (con colección y genéricos), ¡estoy enamorado de FEST! Gracias por compartir.
Guillaume
2
FEST ya no está activo. Utilice AssertJ, que es una bifurcación de FEST. joel-costigliola.github.io/assertj
user64141
17

Además, si se está utilizando JUnit 4.1.1 + Hamcrest 1.3 + Mockito 1.9.5, asegúrese de que no se utilice mockito-all. Contiene clases básicas de Hamcrest. En su lugar, utilice mockito-core. La siguiente configuración funciona:

<dependency>
    <groupId>org.hamcrest</groupId>
    <artifactId>hamcrest-all</artifactId>
    <version>1.3</version>
    <scope>test</scope>
</dependency>
<dependency>
    <groupId>org.mockito</groupId>
    <artifactId>mockito-core</artifactId>
    <version>1.9.5</version>
    <scope>test</scope>
    <exclusions>
        <exclusion>
            <artifactId>hamcrest-core</artifactId>
            <groupId>org.hamcrest</groupId>
        </exclusion>
    </exclusions>
</dependency>
<dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.1.1</version>
    <scope>test</scope>
    <exclusions>
        <exclusion>
            <artifactId>hamcrest-core</artifactId>
            <groupId>org.hamcrest</groupId>
        </exclusion>
    </exclusions>
</dependency>
souser
fuente
4

Dado que las versiones cambian todo el tiempo, publico para que la gente sepa que a partir del 2 de diciembre de 2014, las instrucciones se encuentran en http://www.javacodegeeks.com/2014/03/how-to-test-dependencies-in -a-maven-project-junit-mockito-hamcrest-assertj.html funcionó para mí. Sin embargo, no usé AssertJ, solo estos:

<dependency>
  <groupId>junit</groupId>
  <artifactId>junit</artifactId>
  <version>4.11</version>
  <scope>test</scope>
</dependency>
<dependency>
  <groupId>org.mockito</groupId>
  <artifactId>mockito-core</artifactId>
  <version>1.9.5</version>
  <scope>test</scope>
</dependency>
<dependency>
    <groupId>org.hamcrest</groupId>
    <artifactId>hamcrest-core</artifactId>
    <version>1.3</version>
    <scope>test</scope>
</dependency>
<dependency>
    <groupId>org.hamcrest</groupId>
    <artifactId>hamcrest-library</artifactId>
    <version>1.3</version>
    <scope>test</scope>
</dependency>   
<dependency>
    <groupId>org.objenesis</groupId>
    <artifactId>objenesis</artifactId>
    <version>1.3</version>
    <scope>test</scope>
</dependency>
Michael Osofsky
fuente
1
No es necesario definir las dependencias hamcrest-core y hamcrest-library al mismo tiempo, ya que hamcrest-library ya define hamcrest-core como una dependencia transitiva.
Eugene Maysyuk
3

¿Por qué JUnit incluyó el paquete org.hamcrest en su propia distribución en lugar de animarnos a usar la biblioteca hamcrest original?

Supongo que es porque querían assertThatformar parte de JUnit. Eso significa que la Assertclase tiene que importar la org.hamcrest.Matcherinterfaz y no puede hacerlo a menos que JUnit dependa de Hamcrest o incluya (al menos parte de) Hamcrest. Y supongo que incluir parte de él fue más fácil, por lo que JUnit podría usarse sin dependencias.

MatrixFrog
fuente
2

En 2018 utilizando la mayoría de las bibliotecas modernas:

configurations {
    all {
        testCompile.exclude group: "org.hamcrest", module: "hamcrest-core"
        testCompile.exclude group: "org.hamcrest", module: "hamcrest-library"
    }
}
dependencies {
    testCompile("junit:junit:4.12")
    // testCompile("org.hamcrest:hamcrest-library:1.3")
    // testCompile("org.hamcrest:java-hamcrest:2.0.0.0")
    testCompile("org.hamcrest:hamcrest-junit:2.0.0.0")
}
Gavenkoa
fuente
0

Tanto JUnit-4.12 como JUnit-Dep-4.10 tienen dependencias de Hamcrest de acuerdo con los respectivos archivos .xml.

Una investigación adicional muestra que, aunque la dependencia se realizó en los archivos .xml, la fuente y las clases en los archivos jar. Parece ser una forma de excluir la dependencia en build.gradle ... probándolo para mantener todo limpio.

Solo un fyi

cíclope3324911
fuente
1
No entiendo tu segundo párrafo. Creo que podría haber omitido algunas palabras de lo que quería escribir.
Dan Getz