如何一起使用JUnit和Hamcrest?


88

我不明白JUnit 4.8如何与Hamcrest匹配器一起工作。有内部定义了一些匹配器junit-4.8.jarorg.hamcrest.CoreMatchers。同时,也有一些其他的匹配器hamcrest-all-1.1.jarorg.hamcrest.Matchers。那么,去哪儿呢?我是否应该在项目中明确包含hamcrest JAR并忽略JUnit提供的匹配器?

特别是,我对empty()匹配器感兴趣,并且在任何这些jar中都找不到它。我还需要其他东西吗?:)

还有一个哲学问题:为什么JUnit将org.hamcrest包包含在自己的发行版中而不是鼓励我们使用原始的hamcrest库?

Answers:


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)


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中心。
汤姆


50

如果您使用的Hamcrest版本大于或等于1.2,则应使用junit-dep.jar。这个jar没有Hamcrest类,因此可以避免类加载问题。

从JUnit 4.11开始,junit.jar它本身没有Hamcrest类。不再需要junit-dep.jar


2
从JUnit 4.12开始,似乎不再有junit-dep.jar。是这样吗 如果是这样,我们是否打算使用独立的Hamcrest 1.3罐子?
杰夫·埃文斯

1
回答两个问题:是的。
Stefan Birkner,2015年

25

不能完全回答您的问题,但是您绝对应该尝试FEST-Assert流畅断言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!感谢分享。
纪尧姆

2
FEST不再有效。使用AssertJ,这是FEST的分支。 joel-costigliola.github.io/assertj
user64141 '16

17

另外,如果使用的是JUnit 4.1.1 + Hamcrest 1.3 + Mockito 1.9.5,请确保未使用mockito-all。它包含Hamcrest核心类。请改用嘲笑核心。以下配置有效:

<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

由于版本一直在变化,我发布的消息是让人们知道,截至2014年12月2日,该说明位于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定义为传递性依赖项。
Eugene Maysyuk '18

3

为什么JUnit在自己的发行版中包含org.hamcrest包而不是鼓励我们使用原始的hamcrest库?

我猜这是因为他们希望assertThatJUnit成为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

根据各自的.xml文件,JUnit-4.12和JUnit-Dep-4.10都具有Hamcrest依赖项。

进一步的调查表明,尽管依赖项是在.xml文件中进行的,但其jar文件中是源文件和类。似乎是一种排除build.gradle中的依赖项的方法...对其进行测试以保持所有内容的清洁。

只是一个风


1
我不明白你的第二段。我认为您可能从打算写的文字中遗漏了一些文字?
丹·盖茨
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.