Как использовать JUnit и Hamcrest вместе?

88

Я не могу понять, как JUnit 4.8 должен работать с сопоставителями Hamcrest. Есть некоторые matchers , определенные внутри junit-4.8.jarв org.hamcrest.CoreMatchers. В то же время есть некоторые другие matchers в hamcrest-all-1.1.jarв org.hamcrest.Matchers. Итак, куда идти? Должен ли я явно включать Hamcrest JAR в проект и игнорировать сопоставители, предоставляемые JUnit?

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

И философский вопрос: почему JUnit включил org.hamcrestпакет в свой собственный дистрибутив вместо того, чтобы побуждать нас использовать оригинальную библиотеку hamcrest?

Егор256
источник

Ответы:

49

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

Чтобы использовать это, в junit есть несколько основных сопоставителей. С них можно начать базовые тесты.

Если вы хотите использовать больше сопоставителей, вы можете написать их самостоятельно или использовать библиотеку hamcrest.

В следующем примере показано, как использовать пустое сопоставление в 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 в свой путь сборки)

cpater
источник
2
где именно org.hamcrest.Matchers.empty()находится? Не могли бы вы дать ссылку на файл JAR?
yegor256 06
Вы можете найти все здесь: code.google.com/p/hamcrest и загрузку hamcrest-all.jar здесь: code.google.com/p/hamcrest/downloads/…
cpater
1
Похоже, что hamcrest 1.2 нет в репозитории Maven Central. Это проблема, с которой я столкнулся :(
yegor256 06
5
Hamcrest 1.3 уже выпущен и находится в центре maven.
Tom
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?
Джефф Эванс
1
Ответьте на оба вопроса: да.
Стефан Биркнер
25

Не совсем отвечаю на ваш вопрос, но вам обязательно стоит попробовать FEST-Assert fluent 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
Я просто поменял местами свою библиотеку утверждений. Я был вполне доволен hamcrest, но из-за проблемного включения junit и некоторых сложных для написания тестов (с коллекцией и обобщениями) я знаю, что влюблен в FEST! Спасибо, что поделился.
Guillaume
2
FEST больше не действует. Используйте AssertJ, который является форком FEST. joel-costigliola.github.io/assertj
user64141 07
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, источник и классы - в jar-файлах. Кажется, это способ исключить зависимость в build.gradle ... проверить его, чтобы все было в чистоте.

Просто к сведению

циклоп3324911
источник
1
Я не понимаю ваш второй абзац. Я думаю, вы могли упустить некоторые слова из того, что хотели написать?
Дэн Гетц