关于Java:如何一起使用JUnit和Hamcrest?

How to use JUnit and Hamcrest together?

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

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

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


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

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


junit提供了名为assertThat()的新检查断言方法,该方法使用Matchers并应提供更具可读性的测试代码和更好的故障消息。

要使用此功能,junit中包含一些核心匹配器。您可以从这些开始进行基本测试。

如果要使用更多的匹配器,则可以自己编写或使用hamcrest lib。

下面的示例演示如何在ArrayList上使用空匹配器:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
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)


不能完全回答您的问题,但是您绝对应该尝试FEST-Assert流畅断言API。它与Hamcrest竞争,但API更加轻松,只需要一次静态导入。这是cpater使用FEST提供的代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
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坐标:

1
2
3
4
5
6
<dependency>
  <groupId>org.easytesting</groupId>
  fest-assert</artifactId>
  <version>1.4</version>
  <scope>test</scope>
</dependency>


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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
<dependency>
    <groupId>org.hamcrest</groupId>
    hamcrest-all</artifactId>
    <version>1.3</version>
    <scope>test</scope>
</dependency>
<dependency>
    <groupId>org.mockito</groupId>
    mockito-core</artifactId>
    <version>1.9.5</version>
    <scope>test</scope>
    <exclusions>
        <exclusion>
            hamcrest-core</artifactId>
            <groupId>org.hamcrest</groupId>
        </exclusion>
    </exclusions>
</dependency>
<dependency>
    <groupId>junit</groupId>
    junit</artifactId>
    <version>4.1.1</version>
    <scope>test</scope>
    <exclusions>
        <exclusion>
            hamcrest-core</artifactId>
            <groupId>org.hamcrest</groupId>
        </exclusion>
    </exclusions>
</dependency>

由于版本一直在变化,我发布的消息是让人们知道,截至2014年12月2日,该说明位于http://www.javacodegeeks.com/2014/03/how-to-test-dependencies-in -a-maven-project-junit-mockito-hamcrest-assertj.html为我工作。我没有使用AssertJ,只是这些:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
<dependency>
  <groupId>junit</groupId>
  junit</artifactId>
  <version>4.11</version>
  <scope>test</scope>
</dependency>
<dependency>
  <groupId>org.mockito</groupId>
  mockito-core</artifactId>
  <version>1.9.5</version>
  <scope>test</scope>
</dependency>
<dependency>
    <groupId>org.hamcrest</groupId>
    hamcrest-core</artifactId>
    <version>1.3</version>
    <scope>test</scope>
</dependency>
<dependency>
    <groupId>org.hamcrest</groupId>
    hamcrest-library</artifactId>
    <version>1.3</version>
    <scope>test</scope>
</dependency>  
<dependency>
    <groupId>org.objenesis</groupId>
    objenesis</artifactId>
    <version>1.3</version>
    <scope>test</scope>
</dependency>


why JUnit included org.hamcrest package into its own distribution instead of encouraging us to use original hamcrest library?

我猜这是因为他们希望assertThat成为JUnit的一部分。因此,这意味着Assert类必须导入org.hamcrest.Matcher接口,除非JUnit依赖Hamcrest或包含(至少包括)Hamcrest,否则它不能这样做。而且我想包括其中的一部分会更容易,这样JUnit就可以在没有任何依赖的情况下使用。


在2018年使用最现代的图书馆:

1
2
3
4
5
6
7
8
9
10
11
12
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")
}

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

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

只是一个f.y.i.