Як використовувати JUnit і Hamcrest разом?


88

Я не можу зрозуміти, як JUnit 4.8 повинен працювати з матчерами Hamcrest. Є деякі matchers , певні всередині junit-4.8.jarв org.hamcrest.CoreMatchers. У той же час є деякі інші matchers в hamcrest-all-1.1.jarв org.hamcrest.Matchers. Отже, куди йти? Чи повинен я явно включити в проект JAR hamcrest та ігнорувати збіги, надані JUnit?

Зокрема, я зацікавлений у empty()збігу і не можу знайти його в жодній з цих банок. Мені потрібно щось інше? :)

І філософське запитання: чому JUnit включив org.hamcrestпакет у власний дистрибутив, замість того, щоб заохочувати нас використовувати оригінальну бібліотеку Hamcrest?

Відповіді:


49

junit надає нові методи перевірки затвердження з назвою assertThat (), що використовує Matchers і повинен надавати більш читабельний тестовий код та кращі повідомлення про помилки.

Для цього є кілька основних збігів, включених в junit. Ви можете почати з них для базових тестів.

Якщо ви хочете використовувати більше збігів, ви можете написати їх самостійно або скористатися підніжком.

Наступний приклад демонструє, як використовувати порожній збіг у 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 у свій шлях до збірки)


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 Central.
Том


50

Якщо ви використовуєте 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
Відповідь на обидва запитання: так.
Штефан Біркнер

25

Не точно відповісти на ваше запитання, але вам обов’язково слід спробувати API FEST-Assert для вільних тверджень. Він конкурує з 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();
    }  
}

EDIT: координати Maven:

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

3
Я просто поміняв місцями свою бібліотеку тверджень. Я був цілком задоволений hamcrest, але через проблему включення junit та деякі важкі для написання тести (з колекцією та дженериками) я знаю, що закоханий у FEST! Дякую, що поділились.
Гійом

2
FEST більше не активний. Використовуйте AssertJ, який є форком FEST. joel-costigliola.github.io/assertj
user64141

17

Крім того, якщо використовується 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, оскільки hamcrest-library вже визначає hamcrest-core як транзитивну залежність.
Євген Майсюк

3

чому JUnit включив пакет org.hamcrest у власний дистрибутив замість того, щоб заохочувати нас використовувати оригінальну бібліотеку 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
Я не розумію вашого другого абзацу. Думаю, ви могли пропустити кілька слів із того, що мали намір написати?
Ден Гец,
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.