Jak używać JUnit i Hamcrest razem?

88

Nie mogę zrozumieć, jak JUnit 4.8 powinien współpracować z dopasowującymi się Hamcrest. Istnieją pewne dopasowujących zdefiniowane wewnątrz junit-4.8.jarw org.hamcrest.CoreMatchers. Jednocześnie istnieje kilka innych dopasowujących w hamcrest-all-1.1.jarw org.hamcrest.Matchers. Więc gdzie się udać? Czy mam jawnie dołączyć plik JAR hamcrest do projektu i zignorować elementy dopasowujące dostarczone przez JUnit?

W szczególności interesuje mnie empty()matcher i nie mogę go znaleźć w żadnym z tych słoików. Potrzebuję czegoś innego? :)

I pytanie filozoficzne: dlaczego JUnit umieścił org.hamcrestpakiet we własnej dystrybucji zamiast zachęcać nas do korzystania z oryginalnej biblioteki hamcrest?

yegor256
źródło

Odpowiedzi:

49

junit udostępnia nowe metody asercji sprawdzania o nazwie assertThat (), które używają dopasowań i powinny zapewniać bardziej czytelny kod testowy i lepsze komunikaty o błędach.

Aby tego użyć, junit zawiera kilka podstawowych dopasowań. Możesz zacząć od tych podstawowych testów.

Jeśli chcesz użyć większej liczby dopasowań, możesz napisać je samodzielnie lub użyć hamcrest lib.

Poniższy przykład ilustruje, jak używać pustego dopasowania na tablicy 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()));

    }
}

(Dodałem hamcrest-all.jar do mojej ścieżki budowania)

cpater
źródło
2
gdzie dokładnie org.hamcrest.Matchers.empty()się znajduje? Czy mógłbyś podać link do pliku JAR?
yegor256,
Możesz znaleźć wszystko tutaj: code.google.com/p/hamcrest i pobrać hamcrest-all.jar tutaj: code.google.com/p/hamcrest/downloads/…
cpater
1
Wygląda na to, że hamcrest 1.2 nie znajduje się w repozytorium Maven Central. Oto problem, przed którym stoję :(
yegor256,
5
Hamcrest 1.3 został już wydany i znajduje się w centrum Maven.
Tom
50

Jeśli używasz Hamcrest z wersją wyższą lub równą 1,2, powinieneś użyć junit-dep.jar. Ten słoik nie ma klas Hamcrest, dzięki czemu unikniesz problemów z ładowaniem klas.

Od JUnit 4.11 junit.jarsamo w sobie nie ma klas Hamcrest. Nie ma junit-dep.jarjuż takiej potrzeby .

Stefan Birkner
źródło
2
Wygląda na to, że od JUnit 4.12 nie ma już pliku junit-dep.jar. Czy tak jest? A jeśli tak, czy mamy używać samodzielnego słoika Hamcrest 1.3?
Jeff Evans,
1
Odpowiedz na oba pytania: tak.
Stefan Birkner
25

Nie do końca odpowiadając na Twoje pytanie, ale zdecydowanie powinieneś wypróbować FEST-Assert Fluent Assertions API. Konkuruje z Hamcrestem, ale ma znacznie łatwiejsze API z wymaganym tylko jednym statycznym importem. Oto kod dostarczony przez cpater przy użyciu 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();
    }  
}

EDYCJA: współrzędne Maven:

<dependency>
  <groupId>org.easytesting</groupId>
  <artifactId>fest-assert</artifactId>
  <version>1.4</version>
  <scope>test</scope>
</dependency>
Tomasz Nurkiewicz
źródło
3
Właśnie zmieniłem moją bibliotekę potwierdzeń. Byłem całkiem zadowolony z hamcrestu, ale z powodu problemów z włączaniem junit i niektórych trudnych do napisania testów (z kolekcją i generykami), jestem zakochany w FEST! Dzięki za udostępnienie.
Guillaume,
2
FEST nie jest już aktywny. Użyj AssertJ, który jest rozwidleniem FEST. joel-costigliola.github.io/assertj
user64141
17

Ponadto, jeśli używasz JUnit 4.1.1 + Hamcrest 1.3 + Mockito 1.9.5, upewnij się, że nie jest używane mockito-all. Zawiera podstawowe klasy Hamcrest. Zamiast tego użyj mockito-core. Poniższa konfiguracja działa:

<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
źródło
4

Ponieważ wersje cały czas się zmieniają, piszę, aby poinformować ludzi, że od 2 grudnia 2014 r. Instrukcje znajdują się na stronie http://www.javacodegeeks.com/2014/03/how-to-test-dependencies-in -a-maven-project-junit-mockito-hamcrest-assertj.html pracował dla mnie. Nie korzystałem jednak z AssertJ, tylko te:

<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
źródło
1
Nie ma potrzeby definiowania zależności hamcrest-core i hamcrest-library w tym samym czasie, ponieważ hamcrest-library już definiuje hamcrest-core jako zależność przechodnią.
Eugene Maysyuk
3

dlaczego JUnit włączył pakiet org.hamcrest do własnej dystrybucji zamiast zachęcać nas do korzystania z oryginalnej biblioteki hamcrest?

Wydaje mi się, że to dlatego, że chcieli, assertThataby byli częścią JUnit. Oznacza to, że Assertklasa musi zaimportować org.hamcrest.Matcherinterfejs i nie może tego zrobić, chyba że JUnit albo zależy od Hamcresta, albo zawiera (przynajmniej część) Hamcresta. I myślę, że włączenie części było łatwiejsze, aby JUnit był użyteczny bez żadnych zależności.

MatrixFrog
źródło
2

W 2018 roku przy użyciu większości nowoczesnych bibliotek:

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
źródło
0

Zarówno JUnit-4.12, jak i JUnit-Dep-4.10 mają zależności Hamcrest zgodnie z odpowiednimi plikami .xml.

Dalsze dochodzenie pokazuje, że chociaż zależność wystąpiła w plikach .xml, źródło i klasy w plikach jar. Wydaje się, że jest to sposób na wykluczenie zależności w build.gradle ... przetestowanie go, aby wszystko było czyste.

Tylko fyi

cyclops3324911
źródło
1
Nie rozumiem twojego drugiego akapitu. Myślę, że mogłeś pominąć kilka słów z tego, co chciałeś napisać?
Dan Getz