Bagaimana cara menggunakan JUnit dan Hamcrest secara bersamaan?

89

Saya tidak mengerti bagaimana JUnit 4.8 harus bekerja dengan pencocok Hamcrest. Ada beberapa pencocokan yang ditentukan di junit-4.8.jardalam org.hamcrest.CoreMatchers. Pada saat yang sama ada beberapa matcher lain di hamcrest-all-1.1.jardalam org.hamcrest.Matchers. Jadi, mau kemana? Haruskah saya secara eksplisit memasukkan hamcrest JAR ke dalam proyek dan mengabaikan pencocokan yang disediakan oleh JUnit?

Secara khusus, saya tertarik dengan empty()matcher dan tidak dapat menemukannya di salah satu toples ini. Saya butuh yang lain? :)

Dan pertanyaan filosofis: mengapa JUnit menyertakan org.hamcrestpaket ke distribusinya sendiri alih-alih mendorong kami untuk menggunakan pustaka hamcrest asli?

yegor256
sumber

Jawaban:

49

junit menyediakan metode check assert baru bernama assertThat () yang menggunakan Matchers dan harus menyediakan kode pengujian yang lebih mudah dibaca dan pesan kegagalan yang lebih baik.

Untuk menggunakan ini, ada beberapa pencocokan inti yang disertakan dalam junit. Anda bisa mulai dengan ini untuk tes dasar.

Jika Anda ingin menggunakan lebih banyak matcher, Anda dapat menulisnya sendiri atau menggunakan hamcrest lib.

Contoh berikut menunjukkan cara menggunakan matcher kosong di 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()));

    }
}

(Saya menyertakan hamcrest-all.jar di buildpath saya)

cpater.dll
sumber
2
dimana tepatnya org.hamcrest.Matchers.empty()berada? Bisakah Anda memberi tautan ke file JAR?
yegor256
Anda dapat menemukan semuanya di sini: code.google.com/p/hamcrest dan unduhan hamcrest-all.jar di sini: code.google.com/p/hamcrest/downloads/…
cpater
1
Sepertinya hamcrest 1.2 tidak ada di repositori Pusat Maven. Itulah masalah yang saya hadapi :(
yegor256
5
Hamcrest 1.3 sekarang telah dirilis, dan berada di tengah maven.
Tom
51

Jika Anda menggunakan Hamcrest dengan versi yang lebih besar atau sama dari 1.2, maka Anda harus menggunakan junit-dep.jar. Jar ini tidak memiliki kelas Hamcrest dan oleh karena itu Anda menghindari masalah pemuatan kelas.

Sejak JUnit 4.11, junit.jardirinya sendiri tidak memiliki kelas Hamcrest. Tidak perlu junit-dep.jarlagi.

Stefan Birkner
sumber
2
Sepertinya pada JUnit 4.12, tidak ada lagi junit-dep.jar. Apakah itu masalahnya? Dan jika demikian, apakah kami bermaksud menggunakan stoples Hamcrest 1.3 yang berdiri sendiri?
Jeff Evans
1
Jawab kedua pertanyaan: ya.
Stefan Birkner
25

Tidak benar-benar menjawab pertanyaan Anda, tetapi Anda harus mencoba FEST-Assert fluent assertions API. Ini bersaing dengan Hamcrest, tetapi memiliki API yang jauh lebih mudah dengan hanya satu impor statis yang diperlukan. Berikut adalah kode yang diberikan oleh cpater menggunakan 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: Koordinat Maven:

<dependency>
  <groupId>org.easytesting</groupId>
  <artifactId>fest-assert</artifactId>
  <version>1.4</version>
  <scope>test</scope>
</dependency>
Tomasz Nurkiewicz
sumber
3
Saya baru saja menukar perpustakaan pernyataan saya. Saya cukup puas dengan hamcrest, tetapi karena masalah inklusi junit yang bermasalah dan beberapa tes yang sulit ditulis (dengan collection dan generik), saya tahu jatuh cinta dengan FEST! Terima kasih telah berbagi.
Guillaume
2
FEST tidak lagi aktif. Gunakan AssertJ, yang merupakan cabang dari FEST. joel-costigliola.github.io/assertj
user64141
18

Juga, jika JUnit 4.1.1 + Hamcrest 1.3 + Mockito 1.9.5 digunakan, pastikan mockito-all tidak digunakan. Ini berisi kelas inti Hamcrest. Gunakan mockito-core sebagai gantinya. Konfigurasi di bawah berfungsi:

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

Karena versi berubah sepanjang waktu, saya mengeposkan untuk memberi tahu orang-orang bahwa mulai 2 Desember 2014, petunjuknya ada di http://www.javacodegeeks.com/2014/03/how-to-test-dependencies-in -a-maven-project-junit-mockito-hamcrest-assertj.html berhasil untuk saya. Saya tidak menggunakan AssertJ, hanya ini:

<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
sumber
1
Tidak perlu mendefinisikan kedua dependensi hamcrest-core dan hamcrest-library secara bersamaan karena hamcrest-library sudah mendefinisikan hamcrest-core sebagai dependensi transitif.
Eugene Maysyuk
3

mengapa JUnit menyertakan paket org.hamcrest ke distribusinya sendiri alih-alih mendorong kami untuk menggunakan pustaka hamcrest asli?

Saya rasa itu karena mereka ingin assertThatmenjadi bagian dari JUnit. Jadi itu berarti Assertkelas harus mengimpor org.hamcrest.Matcherantarmuka dan tidak dapat melakukannya kecuali JUnit bergantung pada Hamcrest, atau menyertakan (setidaknya sebagian) Hamcrest. Dan saya rasa memasukkan sebagian darinya lebih mudah, sehingga JUnit akan dapat digunakan tanpa ketergantungan apa pun.

MatrixFrog
sumber
2

Di 2018 menggunakan sebagian besar perpustakaan modern:

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.dll
sumber
0

Baik JUnit-4.12 dan JUnit-Dep-4.10 memiliki dependensi Hamcrest sesuai dengan file .xml masing-masing.

Penyelidikan lebih lanjut menunjukkan bahwa meskipun ketergantungan dibuat dalam file .xml, sumber dan kelas dalam jars. Tampaknya ini adalah cara untuk mengecualikan dependensi di build.gradle ... mengujinya untuk menjaga semuanya tetap bersih.

Hanya fyi

cyclops3324911
sumber
1
Saya tidak mengerti paragraf kedua Anda. Saya pikir Anda mungkin telah melewatkan beberapa kata dari apa yang ingin Anda tulis?
Dan Getz