Làm thế nào để sử dụng JUnit và Hamcrest cùng nhau?


88

Tôi không thể hiểu cách JUnit 4.8 sẽ hoạt động với các trình khớp nối Hamcrest. Có một số đối sánh được xác định bên junit-4.8.jartrong org.hamcrest.CoreMatchers. Đồng thời có một số đối tác khác tham hamcrest-all-1.1.jargia org.hamcrest.Matchers. Vậy, đi đâu? Tôi có nên đưa hamcrest JAR vào dự án một cách rõ ràng và bỏ qua các đối tác do JUnit cung cấp không?

Đặc biệt, tôi quan tâm đến empty()matcher và không thể tìm thấy nó trong bất kỳ lọ nào trong số này. Tôi cần thứ gì khác? :)

Và một câu hỏi triết học: tại sao JUnit lại đưa org.hamcrestgói vào bản phân phối của chính nó thay vì khuyến khích chúng ta sử dụng thư viện hamcrest gốc?

Câu trả lời:


49

junit cung cấp các phương thức xác nhận kiểm tra mới có tên khẳng định là khẳng định () sử dụng Matchers và sẽ cung cấp mã kiểm tra dễ đọc hơn và thông báo lỗi tốt hơn.

Để sử dụng điều này, có một số đối sánh cốt lõi được bao gồm trong junit. Bạn có thể bắt đầu với những điều này cho các bài kiểm tra cơ bản.

Nếu bạn muốn sử dụng nhiều trình khớp hơn, bạn có thể tự viết chúng hoặc sử dụng hamcrest lib.

Ví dụ sau minh họa cách sử dụng bộ so khớp trống trên 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()));

    }
}

(Tôi đã bao gồm hamcrest-all.jar trong đường dẫn xây dựng của mình)


2
chính xác org.hamcrest.Matchers.empty()là nằm ở đâu? Bạn có thể vui lòng cung cấp một liên kết đến tệp JAR không?
yegor256

Bạn có thể tìm thấy tất cả ở đây: code.google.com/p/hamcrest và tải xuống hamcrest-all.jar tại đây: code.google.com/p/hamcrest/downloads/…
cpater

1
Có vẻ như hamcrest 1.2 không có trong kho Maven Central. Đó là vấn đề tôi đang phải đối mặt với :(
yegor256

5
Hamcrest 1.3 hiện đã được phát hành và đang ở trung tâm maven.
Tom


50

Nếu bạn đang sử dụng Hamcrest có phiên bản lớn hơn hoặc bằng 1.2, thì bạn nên sử dụng junit-dep.jar. Bình này không có lớp Hamcrest và do đó bạn tránh được các vấn đề về tải lớp.

junit.jarbản thân JUnit 4.11 không có lớp Hamcrest. Không cần thiết junit-dep.jarnữa.


2
Có vẻ như kể từ JUnit 4.12, không còn junit-dep.jar nữa. Có phải vậy không? Và nếu vậy, chúng tôi muốn sử dụng lọ Hamcrest 1.3 độc lập?
Jeff Evans

1
Trả lời cho cả hai câu hỏi: có.
Stefan Birkner

25

Không trả lời chính xác câu hỏi của bạn, nhưng bạn chắc chắn nên thử API xác nhận thông thạo FEST-Assert . Nó cạnh tranh với Hamcrest, nhưng có một API dễ dàng hơn nhiều với chỉ một lần nhập tĩnh được yêu cầu. Đây là mã do cpater cung cấp bằng 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();
    }  
}

CHỈNH SỬA: Tọa độ Maven:

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

3
Tôi vừa hoán đổi thư viện xác nhận của mình. Tôi khá hài lòng với hamcrest, nhưng vì nội dung bao gồm có vấn đề và một số bài kiểm tra khó viết (với bộ sưu tập và generic), tôi biết là yêu FEST! Cám ơn vì đã chia sẻ.
Guillaume

2
FEST không còn hoạt động. Sử dụng AssertJ, một nhánh của FEST. joel-costigliola.github.io/assertj
user64141

17

Ngoài ra, nếu JUnit 4.1.1 + Hamcrest 1.3 + Mockito 1.9.5 đang được sử dụng, hãy đảm bảo rằng mockito-all không được sử dụng. Nó chứa các lớp lõi Hamcrest. Thay vào đó, hãy sử dụng mockito-core. Cấu hình dưới đây hoạt động:

<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

Vì các phiên bản luôn thay đổi, tôi đăng để cho mọi người biết rằng kể từ ngày 2 tháng 12 năm 2014, hướng dẫn tại http://www.javacodegeeks.com/2014/03/how-to-test-dependencies-in -a-maven-project-junit-mockito-hamcrest-khẳng địnhj.html đã làm việc cho tôi. Tuy nhiên, tôi đã không sử dụng AssertJ, chỉ những điều này:

<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
Không cần phải xác định cả hai phụ thuộc hamcrest-core và hamcrest-library cùng một lúc vì thư viện hamcrest đã định nghĩa hamcrest-core là một phụ thuộc bắc cầu.
Eugene Maysyuk

3

tại sao JUnit lại đưa gói org.hamcrest vào bản phân phối của chính nó thay vì khuyến khích chúng tôi sử dụng thư viện hamcrest gốc?

Tôi đoán đó là vì họ muốn assertThattrở thành một phần của JUnit. Vì vậy, điều đó có nghĩa là Assertlớp phải nhập org.hamcrest.Matchergiao diện và nó không thể làm điều đó trừ khi JUnit phụ thuộc vào Hamcrest hoặc bao gồm (ít nhất là một phần của) Hamcrest. Và tôi đoán việc bao gồm một phần của nó dễ dàng hơn, để JUnit có thể sử dụng được mà không cần bất kỳ phụ thuộc nào.


2

Năm 2018 sử dụng hầu hết các thư viện hiện đại:

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

Cả JUnit-4.12 và JUnit-Dep-4.10 đều có các phụ thuộc Hamcrest theo các tệp .xml tương ứng.

Điều tra sâu hơn cho thấy rằng mặc dù sự phụ thuộc được thực hiện trong các tệp .xml, nguồn và các lớp trong các lọ. Đây dường như là một cách loại trừ sự phụ thuộc trong build.gradle ... thử nghiệm nó để giữ mọi thứ sạch sẽ.

Chỉ là một fyi


1
Tôi không hiểu đoạn thứ hai của bạn. Tôi nghĩ bạn có thể đã bỏ sót một số từ những gì bạn muốn viết?
Dan Getz
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.