Come utilizzare JUnit e Hamcrest insieme?


88

Non riesco a capire come JUnit 4.8 dovrebbe funzionare con i matcher di Hamcrest. Ci sono alcuni matcher definiti all'interno junit-4.8.jardi org.hamcrest.CoreMatchers. Allo stesso tempo ci sono altri matcher hamcrest-all-1.1.jarin org.hamcrest.Matchers. Allora, dove andare? Devo includere esplicitamente JAR hamcrest nel progetto e ignorare i matcher forniti da JUnit?

In particolare, sono interessato al empty()matcher e non riesco a trovarlo in nessuno di questi barattoli. Ho bisogno di qualcos'altro? :)

E una domanda filosofica: perché JUnit ha incluso il org.hamcrestpacchetto nella propria distribuzione invece di incoraggiarci a utilizzare la libreria hamcrest originale?

Risposte:


49

junit fornisce nuovi metodi di asserzione di controllo denominati assertThat () che utilizza Matcher e dovrebbe fornire un codice di prova più leggibile e messaggi di errore migliori.

Per usarlo ci sono alcuni core matcher inclusi in junit. Puoi iniziare con questi per i test di base.

Se vuoi usare più matcher puoi scriverli da solo o usare hamcrest lib.

L'esempio seguente mostra come utilizzare il matcher vuoto su un 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()));

    }
}

(Ho incluso hamcrest-all.jar nel mio buildpath)


2
dove org.hamcrest.Matchers.empty()si trova esattamente ? Potresti fornire un collegamento al file JAR?
yegor256

Puoi trovare tutto qui: code.google.com/p/hamcrest e il download di hamcrest-all.jar qui: code.google.com/p/hamcrest/downloads/…
cpater

1
Sembra che hamcrest 1.2 non sia nel repository Maven Central. Questo è il problema che sto affrontando :(
yegor256

5
Hamcrest 1.3 è stato ora rilasciato ed è in Maven Central.
Tom


50

Se stai usando un Hamcrest con una versione maggiore o uguale a 1.2, dovresti usare l'estensione junit-dep.jar. Questo vaso non ha classi Hamcrest e quindi eviti problemi di caricamento classi.

A partire da JUnit 4.11, lo junit.jarstesso non ha classi Hamcrest. Non ce n'è più bisogno junit-dep.jar.


2
Sembra che a partire da JUnit 4.12 non ci sia più junit-dep.jar. È così? E se è così, dovremmo usare il barattolo Hamcrest 1.3 autonomo?
Jeff Evans

1
Risposta a entrambe le domande: sì.
Stefan Birkner

25

Non rispondendo esattamente alla tua domanda, ma dovresti assolutamente provare l' API di asserzioni fluenti FEST-Assert . È in concorrenza con Hamcrest, ma ha un'API molto più semplice con una sola importazione statica richiesta. Ecco il codice fornito da cpater utilizzando 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();
    }  
}

EDIT: coordinate di Maven:

<dependency>
  <groupId>org.easytesting</groupId>
  <artifactId>fest-assert</artifactId>
  <version>1.4</version>
  <scope>test</scope>
</dependency>

3
Ho appena scambiato la mia libreria di affermazioni. Sono rimasto abbastanza soddisfatto di hamcrest, ma a causa delle cose problematiche di inclusione di junit e di alcuni test difficili da scrivere (con raccolta e generici), sono innamorato di FEST! Grazie per la condivisione.
Guillaume

2
FEST non è più attivo. Usa AssertJ, che è un fork di FEST. joel-costigliola.github.io/assertj
user64141

17

Inoltre, se si utilizza JUnit 4.1.1 + Hamcrest 1.3 + Mockito 1.9.5, assicurarsi che mockito-all non sia utilizzato. Contiene le classi principali di Hamcrest. Usa invece mockito-core. La configurazione seguente funziona:

<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>

4

Poiché le versioni cambiano continuamente, sto postando per far sapere alle persone che dal 2 dicembre 2014, le istruzioni su http://www.javacodegeeks.com/2014/03/how-to-test-dependencies-in -a-maven-project-junit-mockito-hamcrest-assertj.html ha funzionato per me. Tuttavia, non ho usato AssertJ, solo questi:

<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>

1
Non è necessario definire contemporaneamente le dipendenze hamcrest-core e hamcrest-library poiché la libreria hamcrest definisce già hamcrest-core come dipendenza transitiva.
Eugene Maysyuk

3

perché JUnit ha incluso il pacchetto org.hamcrest nella propria distribuzione invece di incoraggiarci a usare la libreria hamcrest originale?

Immagino sia perché volevano che facessero assertThatparte di JUnit. Quindi questo significa che la Assertclasse deve importare l' org.hamcrest.Matcherinterfaccia e non può farlo a meno che JUnit non dipenda da Hamcrest o includa (almeno parte di) Hamcrest. E immagino che includerne una parte sia stato più semplice, in modo che JUnit fosse utilizzabile senza dipendenze.


2

Nel 2018 utilizzando le biblioteche più moderne:

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")
}

0

Sia JUnit-4.12 che JUnit-Dep-4.10 hanno dipendenze Hamcrest secondo i rispettivi file .xml.

Ulteriori indagini mostrano che sebbene la dipendenza sia stata creata nei file .xml, l'origine e le classi nei file jar. Sembra essere un modo per escludere la dipendenza in build.gradle ... provarlo per mantenere tutto pulito.

Solo un fyi


1
Non capisco il tuo secondo paragrafo. Penso che potresti aver tralasciato alcune parole di quello che intendevi scrivere?
Dan Getz
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.