จะใช้ JUnit และ Hamcrest ร่วมกันได้อย่างไร?


89

ฉันไม่เข้าใจว่า JUnit 4.8 ควรทำงานกับ Hamcrest matchers ได้อย่างไร มี matchers บางที่กำหนดไว้ด้านในเป็นในjunit-4.8.jar org.hamcrest.CoreMatchersในขณะเดียวกันก็มีผู้จับคู่อื่น ๆhamcrest-all-1.1.jarเข้าorg.hamcrest.Matchersมา แล้วจะไปไหนดี? ฉันจะรวม hamcrest JAR ไว้ในโปรเจ็กต์อย่างชัดเจนและไม่สนใจตัวจับคู่ที่ JUnit จัดหาให้หรือไม่

โดยเฉพาะอย่างยิ่งฉันสนใจเรื่องการempty()จับคู่และหาไม่พบในขวดเหล่านี้ ฉันต้องการอย่างอื่น? :)

และคำถามเชิงปรัชญา: ทำไม JUnit รวมorg.hamcrestแพ็คเกจไว้ในการแจกจ่ายของตัวเองแทนที่จะสนับสนุนให้เราใช้ห้องสมุดแฮมเครสต์ดั้งเดิม

คำตอบ:


49

junit มีวิธีการตรวจสอบการยืนยันแบบใหม่ที่ชื่อว่า assertThat () ซึ่งใช้ Matchers และควรให้รหัสทดสอบที่อ่านได้มากขึ้นและข้อความแสดงความล้มเหลวที่ดีขึ้น

ในการใช้สิ่งนี้มีตัวจับคู่หลักบางตัวที่รวมอยู่ใน Junit คุณสามารถเริ่มจากสิ่งเหล่านี้สำหรับการทดสอบขั้นพื้นฐาน

หากคุณต้องการใช้ตัวจับคู่มากขึ้นคุณสามารถเขียนด้วยตัวเองหรือใช้ hamcrest lib

ตัวอย่างต่อไปนี้แสดงวิธีใช้ตัวจับคู่ว่างบน 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()));

    }
}

(ฉันรวม hamcrest-all.jar ไว้ใน buildpath ของฉัน)


2
org.hamcrest.Matchers.empty()ตั้งอยู่ที่ไหนกันแน่? คุณกรุณาให้ลิงค์ไปยังไฟล์ JAR ได้หรือไม่?
yegor256

คุณสามารถค้นหาทั้งหมดได้ที่นี่: code.google.com/p/hamcrestและดาวน์โหลด hamcrest-all.jar ที่นี่: code.google.com/p/hamcrest/downloads/…
cpater

1
ดูเหมือนว่า hamcrest 1.2 ไม่ได้อยู่ในที่เก็บ Maven Central นั่นคือปัญหาที่ฉันกำลังเผชิญ :(
yegor256

5
Hamcrest 1.3 ได้รับการเผยแพร่แล้วและอยู่ในศูนย์กลางของ maven
ทอม


51

หากคุณใช้ Hamcrest กับเวอร์ชันที่มากกว่าหรือเท่ากับ 1.2 คุณควรใช้ไฟล์junit-dep.jar. โถนี้ไม่มีคลาส Hamcrest ดังนั้นคุณจึงหลีกเลี่ยงปัญหาการโหลดคลาส

เนื่องจาก JUnit 4.11 junit.jarตัวเองไม่มีคลาส Hamcrest ไม่มีความจำเป็นjunit-dep.jarอีกต่อไป


2
ดูเหมือนว่าใน JUnit 4.12 จะไม่มี junit-dep.jar อีกต่อไป เป็นอย่างนั้นหรือ? และถ้าเป็นเช่นนั้นเราควรใช้โถ Hamcrest 1.3 แบบสแตนด์อโลนหรือไม่?
Jeff Evans

1
ตอบคำถามทั้งสองข้อ: ใช่
Stefan Birkner

25

ไม่ได้ตอบคำถามของคุณอย่างตรงไปตรงมา แต่คุณควรลองใช้FEST-Assert assertions API อย่างคล่องแคล่ว มันแข่งขันกับ Hamcrest แต่มี API ที่ง่ายกว่ามากโดยต้องมีการนำเข้าแบบคงที่เพียงรายการเดียว นี่คือรหัสที่จัดทำโดยcpaterโดยใช้ 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();
    }  
}

แก้ไข: พิกัด Maven:

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

3
ฉันเพิ่งเปลี่ยนคลังคำยืนยันของฉัน ฉันค่อนข้างพอใจกับแฮมเครสต์ แต่เนื่องจากสิ่งที่รวมปัญหาของจูนิทและการทดสอบการเขียนที่ยาก (พร้อมคอลเลกชันและชื่อสามัญ) ฉันรู้ว่าหลงรัก FEST! ขอบคุณสำหรับการแบ่งปัน.
Guillaume

2
FEST ไม่ทำงานอีกต่อไป ใช้ AssertJ ซึ่งเป็นทางแยกของ FEST joel-costigliola.github.io/assertj
user64141

18

นอกจากนี้หากใช้ JUnit 4.1.1 + Hamcrest 1.3 + Mockito 1.9.5 ตรวจสอบว่าไม่ได้ใช้ mockito-all ประกอบด้วยคลาสหลักของ Hamcrest ใช้ mockito-core แทน การกำหนดค่าด้านล่างใช้งานได้:

<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

เนื่องจากเวอร์ชันมีการเปลี่ยนแปลงตลอดเวลาฉันจึงโพสต์เพื่อแจ้งให้ทุกคนทราบว่า ณ วันที่ 2 ธันวาคม 2014 คำแนะนำที่http://www.javacodegeeks.com/2014/03/how-to-test-dependencies-in -a-maven-project-junit-mockito-hamcrest-assertj.htmlทำงานให้ฉัน ฉันไม่ได้ใช้ AssertJ เพียงแค่นี้:

<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
ไม่จำเป็นต้องกำหนดทั้ง hamcrest-core และ hamcrest-library dependencies ในเวลาเดียวกันเนื่องจาก hamcrest-library ได้กำหนด hamcrest-core แล้วว่าเป็นการพึ่งพาส
Eugene Maysyuk

3

ทำไม JUnit รวมแพ็คเกจ org.hamcrest ไว้ในการแจกจ่ายของตัวเองแทนที่จะสนับสนุนให้เราใช้ห้องสมุดแฮมเครสต์ดั้งเดิม

ฉันเดาว่าเป็นเพราะพวกเขาต้องการassertThatเป็นส่วนหนึ่งของ JUnit นั่นหมายความว่าAssertคลาสต้องนำเข้าorg.hamcrest.Matcherอินเทอร์เฟซและไม่สามารถทำเช่นนั้นได้เว้นแต่ JUnit จะขึ้นอยู่กับ Hamcrest หรือรวม (อย่างน้อยส่วนหนึ่ง) Hamcrest และฉันเดาว่าการรวมส่วนหนึ่งของมันนั้นง่ายกว่าดังนั้น JUnit จะใช้งานได้โดยไม่ต้องพึ่งพาใด ๆ


2

ในปี 2018 โดยใช้ห้องสมุดที่ทันสมัยที่สุด:

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

ทั้ง JUnit-4.12 และ JUnit-Dep-4.10 มีการอ้างอิง Hamcrest ตามไฟล์. xml ที่เกี่ยวข้อง

การตรวจสอบเพิ่มเติมแสดงให้เห็นว่าแม้ว่าการอ้างอิงจะถูกสร้างขึ้นในไฟล์. xml ซอร์สและคลาสในไห ดูเหมือนว่าจะเป็นวิธีการยกเว้นการพึ่งพาใน build.gradle ... การทดสอบเพื่อให้ทุกอย่างสะอาด

เพียงแค่ fyi


1
ฉันไม่เข้าใจย่อหน้าที่สองของคุณ ฉันคิดว่าคุณอาจจะไม่ได้พูดบางคำจากสิ่งที่คุณตั้งใจจะเขียน?
Dan Getz
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.