Wie verwende ich JUnit und Hamcrest zusammen?

87

Ich kann nicht verstehen, wie JUnit 4.8 mit Hamcrest-Matchern funktionieren soll. Es gibt einige Matcher innen definiert junit-4.8.jarin org.hamcrest.CoreMatchers. Zur gleichen Zeit gibt es einige andere Matcher hamcrest-all-1.1.jarin org.hamcrest.Matchers. Also, wohin soll es gehen? Soll ich hamcrest JAR explizit in das Projekt aufnehmen und von JUnit bereitgestellte Matcher ignorieren?

Insbesondere interessiere ich mich für empty()Matcher und kann es in keinem dieser Gläser finden. Ich brauche noch etwas :) :)

Und eine philosophische Frage: Warum hat JUnit das org.hamcrestPaket in seine eigene Distribution aufgenommen, anstatt uns zu ermutigen, die ursprüngliche Hamcrest-Bibliothek zu verwenden?

yegor256
quelle

Antworten:

49

junit bietet neue Check-Assert-Methoden mit dem Namen assertThat (), die Matcher verwenden und einen besser lesbaren Testcode und bessere Fehlermeldungen bereitstellen sollten.

Um dies zu nutzen, sind in Junit einige Core Matcher enthalten. Sie können damit für grundlegende Tests beginnen.

Wenn Sie mehr Matcher verwenden möchten, können Sie diese selbst schreiben oder die hamcrest lib verwenden.

Das folgende Beispiel zeigt, wie der leere Matcher in einer ArrayList verwendet wird:

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()));

    }
}

(Ich habe die hamcrest-all.jar in meinen Buildpath aufgenommen.)

cpater
quelle
2
wo genau org.hamcrest.Matchers.empty()befindet sich Könnten Sie bitte einen Link zur JAR-Datei geben?
yegor256
Sie finden alles hier: code.google.com/p/hamcrest und den Download von hamcrest-all.jar hier: code.google.com/p/hamcrest/downloads/…
cpater
1
Hamcrest 1.2 befindet sich anscheinend nicht im Maven Central-Repository. Das ist das Problem, mit dem ich konfrontiert bin :(
yegor256
5
Hamcrest 1.3 wurde jetzt veröffentlicht und befindet sich in Maven Central.
Tom
50

Wenn Sie ein Hamcrest mit einer Version größer oder gleich 1.2 verwenden, sollten Sie das verwenden junit-dep.jar. Dieses Glas hat keine Hamcrest-Klassen und daher vermeiden Sie Probleme beim Laden von Klassen.

Seit JUnit 4.11 hat das junit.jarselbst keine Hamcrest-Klassen mehr. Es besteht keine Notwendigkeit junit-dep.jarmehr.

Stefan Birkner
quelle
2
Ab JUnit 4.12 scheint es kein junit-dep.jar mehr zu geben. Ist das der Fall? Und wenn ja, sollen wir das eigenständige Hamcrest 1.3-Glas verwenden?
Jeff Evans
1
Antwort auf beide Fragen: ja.
Stefan Birkner
25

Sie beantworten Ihre Frage nicht genau, sollten jedoch unbedingt die FEST-Assert-API für fließende Zusicherungen ausprobieren . Es konkurriert mit Hamcrest, hat aber eine viel einfachere API mit nur einem statischen Import. Hier ist der Code, den cpater mit FEST bereitstellt :

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: Maven Koordinaten:

<dependency>
  <groupId>org.easytesting</groupId>
  <artifactId>fest-assert</artifactId>
  <version>1.4</version>
  <scope>test</scope>
</dependency>
Tomasz Nurkiewicz
quelle
3
Ich habe gerade meine Assertionsbibliothek getauscht. Ich war ziemlich zufrieden mit Hamcrest, aber wegen des problematischen Einschlussmaterials und einiger schwer zu schreibender Tests (mit Sammlung und Generika) bin ich in FEST verliebt! Danke für das Teilen.
Guillaume
2
FEST ist nicht mehr aktiv. Verwenden Sie AssertJ, eine Gabelung von FEST. joel-costigliola.github.io/assertj
user64141
17

Wenn JUnit 4.1.1 + Hamcrest 1.3 + Mockito 1.9.5 verwendet wird, stellen Sie sicher, dass Mockito-All nicht verwendet wird. Es enthält Hamcrest-Kernklassen. Verwenden Sie stattdessen Mockito-Core. Die folgende Konfiguration funktioniert:

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

Da sich die Versionen ständig ändern, poste ich, um die Leute darüber zu informieren, dass ab dem 2. Dezember 2014 die Anweisungen unter http://www.javacodegeeks.com/2014/03/how-to-test-dependencies-in -a-maven-project-junit-mockito-hamcrest-assertj.html hat bei mir funktioniert. Ich habe AssertJ jedoch nicht verwendet, nur diese:

<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
quelle
1
Es ist nicht erforderlich, sowohl Hamcrest-Core- als auch Hamcrest-Library-Abhängigkeiten gleichzeitig zu definieren, da die Hamcrest-Library Hamcrest-Core bereits als transitive Abhängigkeit definiert.
Eugene Maysyuk
3

Warum hat JUnit das Paket org.hamcrest in seine eigene Distribution aufgenommen, anstatt uns zu ermutigen, die ursprüngliche Hamcrest-Bibliothek zu verwenden?

Ich würde vermuten, das liegt daran, dass sie wollten assertThat, dass das Teil von JUnit wird. Das bedeutet, dass die AssertKlasse die org.hamcrest.MatcherSchnittstelle importieren muss und dies nur tun kann, wenn JUnit entweder von Hamcrest abhängt oder (zumindest einen Teil von) Hamcrest enthält. Und ich denke, ein Teil davon war einfacher, so dass JUnit ohne Abhängigkeiten verwendet werden kann.

MatrixFrog
quelle
2

Im Jahr 2018 mit den meisten modernen Bibliotheken:

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

Sowohl JUnit-4.12 als auch JUnit-Dep-4.10 weisen Hamcrest-Abhängigkeiten gemäß den jeweiligen XML-Dateien auf.

Weitere Untersuchungen zeigen, dass, obwohl die Abhängigkeit in den XML-Dateien hergestellt wurde, die Quelle und die Klassen in den Jars. Dies scheint eine Möglichkeit zu sein, die Abhängigkeit in build.gradle auszuschließen ... sie zu testen, um alles sauber zu halten.

Nur eine Info

cyclops3324911
quelle
1
Ich verstehe Ihren zweiten Absatz nicht. Ich denke, Sie haben vielleicht einige Worte aus dem weggelassen, was Sie schreiben wollten?
Dan Getz