Comment utiliser JUnit et Hamcrest ensemble?

87

Je ne comprends pas comment JUnit 4.8 devrait fonctionner avec les matchers Hamcrest. Il y a des matchers définis à l'intérieur junit-4.8.jarde org.hamcrest.CoreMatchers. En même temps , il y a quelques autres matchers dans hamcrest-all-1.1.jardans org.hamcrest.Matchers. Alors, où aller? Dois-je inclure explicitement le JAR hamcrest dans le projet et ignorer les correspondances fournies par JUnit?

En particulier, je suis intéressé par empty()matcher et je ne le trouve dans aucun de ces pots. J'ai besoin d'autre chose? :)

Et une question philosophique: pourquoi JUnit a inclus le org.hamcrestpackage dans sa propre distribution au lieu de nous encourager à utiliser la bibliothèque hamcrest originale?

yegor256
la source

Réponses:

49

junit fournit de nouvelles méthodes de vérification d'assert nommées assertThat () qui utilisent Matchers et devraient fournir un code de test plus lisible et de meilleurs messages d'échec.

Pour l'utiliser, il y a quelques matchers de base inclus dans junit. Vous pouvez commencer avec ces derniers pour les tests de base.

Si vous souhaitez utiliser plus de matchers, vous pouvez les écrire vous-même ou utiliser la bibliothèque hamcrest.

L'exemple suivant montre comment utiliser le matcher vide sur 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()));

    }
}

(J'ai inclus le hamcrest-all.jar dans mon buildpath)

cpater
la source
2
org.hamcrest.Matchers.empty()se trouve exactement ? Pourriez-vous s'il vous plaît donner un lien vers le fichier JAR?
yegor256
Vous pouvez tout trouver ici: code.google.com/p/hamcrest et le téléchargement de hamcrest-all.jar ici: code.google.com/p/hamcrest/downloads/…
cpater
1
On dirait que hamcrest 1.2 n'est pas dans le référentiel Maven Central. C'est le problème auquel je suis confronté :(
yegor256
5
Hamcrest 1.3 est maintenant disponible et se trouve dans maven central.
Tom
50

Si vous utilisez un Hamcrest avec une version supérieure ou égale à 1.2, vous devez utiliser le junit-dep.jar. Ce fichier jar n'a pas de classes Hamcrest et vous évitez donc les problèmes de chargement de classes.

Depuis JUnit 4.11, le junit.jarlui - même n'a pas de classes Hamcrest. Il n'y en a plus besoin junit-dep.jar.

Stefan Birkner
la source
2
Il semble que depuis JUnit 4.12, il n'y ait plus de junit-dep.jar. Est-ce le cas? Et si oui, sommes-nous censés utiliser le pot autonome Hamcrest 1.3?
Jeff Evans
1
Réponse aux deux questions: oui.
Stefan Birkner
25

Ne répond pas exactement à votre question, mais vous devez absolument essayer l' API d'assertions fluentes FEST-Assert . Il est en concurrence avec Hamcrest, mais dispose d'une API beaucoup plus simple avec une seule importation statique requise. Voici le code fourni par cpater en utilisant 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: Coordonnées Maven:

<dependency>
  <groupId>org.easytesting</groupId>
  <artifactId>fest-assert</artifactId>
  <version>1.4</version>
  <scope>test</scope>
</dependency>
Tomasz Nurkiewicz
la source
3
Je viens d'échanger ma bibliothèque d'assertions. J'étais assez satisfait de hamcrest, mais à cause des problèmes d'inclusion problématiques et des tests difficiles à écrire (avec collection et génériques), je sais que je suis amoureux de FEST! Merci d'avoir partagé.
Guillaume
2
FEST n'est plus actif. Utilisez AssertJ, qui est un fork de FEST. joel-costigliola.github.io/assertj
user64141
17

Aussi, si JUnit 4.1.1 + Hamcrest 1.3 + Mockito 1.9.5 sont utilisés, assurez-vous que mockito-all n'est pas utilisé. Il contient les classes de base Hamcrest. Utilisez plutôt mockito-core. La configuration ci-dessous fonctionne:

<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
la source
4

Étant donné que les versions changent constamment, je poste pour informer les gens qu'à compter du 2 décembre 2014, les instructions à l' adresse http://www.javacodegeeks.com/2014/03/how-to-test-dependencies-in -a-maven-project-junit-mockito-hamcrest-assertj.html a fonctionné pour moi. Cependant, je n'ai pas utilisé AssertJ, juste ceux-ci:

<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
la source
1
Il n'est pas nécessaire de définir à la fois les dépendances hamcrest-core et hamcrest-library en même temps puisque la hamcrest-library définit déjà hamcrest-core comme une dépendance transitive.
Eugene Maysyuk
3

pourquoi JUnit a inclus le package org.hamcrest dans sa propre distribution au lieu de nous encourager à utiliser la bibliothèque hamcrest originale?

Je suppose que c'est parce qu'ils voulaient que le assertThatfasse partie de JUnit. Cela signifie que la Assertclasse doit importer l' org.hamcrest.Matcherinterface et qu'elle ne peut pas le faire à moins que JUnit ne dépende de Hamcrest, ou n'inclue (au moins une partie de) Hamcrest. Et je suppose que l'inclusion d'une partie était plus facile, de sorte que JUnit serait utilisable sans aucune dépendance.

MatrixFrog
la source
2

En 2018, en utilisant la plupart des bibliothèques modernes:

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
la source
0

JUnit-4.12 et JUnit-Dep-4.10 ont des dépendances Hamcrest selon les fichiers .xml respectifs.

Une enquête plus approfondie montre que bien que la dépendance ait été faite dans les fichiers .xml, la source et les classes dans les fichiers jars. Cela semble être un moyen d'exclure la dépendance dans build.gradle ... le tester pour que tout reste propre.

Juste un fyi

cyclope3324911
la source
1
Je ne comprends pas votre deuxième paragraphe. Je pense que vous avez peut-être omis certains mots de ce que vous vouliez écrire?
Dan Getz