03-Matchers

Matchers是JUnit框架的外部补充。Matchers在Junit内部被称为Hamcrest框架。JUnit 4.8.2内置Hamcrest,所以你不必下载它,并自己添加。

Matcher与org.junit.Assert.assertThat()方法一起使用,如下所示:

1
2
3
public void assertThat(Object o, Matcher matcher){
...
}

您可以实现自己的Matcher,但JUnit(Hamcrest)附带了一些可以使用的内置匹配器。 这里有几个例子:

1
2
3
4
5
6
7
8
9
10
11
12
import static org.junit.Assert.*;
import static org.hamcrest.CoreMatchers.*;
import org.junit.Test;

public class MyMatcherTest {

@Test
public void testWithMatchers() {
assertThat("this string", is("this string"));
assertThat(123, is(123));
}
}

assertThat()方法接受一个对象和一个Matcher实现。Matcher确定测试是否通过或失败。assertThat()方法只是关注“plumming” - 意思是使用给定的对象来调用Matcher。JUnit(Hamcrest)附带了可以使用的内置Matcher的集合。在上面的示例中,org.hamcrest.CoreMatchers.is()方法用于创建Matcher。如果比较的两个值相等,则返回的匹配器is()返回true,否则返回false。

如果Matcher返回false,则assertThat方法会抛出异常。如果Matcher返回true,则assertThat()方法返回正常。Matcher如何返回true或false,我将在本文后面回到。 现在只是想象它可以。

Chaining Matchers

您可以链接一些Matcher进行使用,例如:

1
2
3
4
5
6
@Test
public void testWithMatchers() {

assertThat(123, not( is(345) ) );

}

注意链接的呼叫不是(is(345))。 这真的是两个匹配的组合。 is()方法返回一个Matcher,而not()方法返回另一个Matchers。 由not()返回的Matcher将否定作为输入给出的Matcher的Matcher输出。 在这种情况下,它是由is()方法返回的匹配器的输出,被否定。

Core Matchers

在开始实现自己的Matcher之前,您应该看看JUnit附带的核心Matcher。 这是一个Matcher方法的列表:

Core
    any()     匹配一切
    is()     检查给定对象是否相等的Matcher 
    describedAs()     向Matcher添加说明

Logical
    allOf() 获取一组Matcher,并且所有Matcher必须与目标对象匹配
    anyOf()     获取一组Matcher,并且至少有一个Matcher必须报告它与目标对象匹配。
    not()     取消先前匹配器的输出
 Object
    equalTo() 检查给定对象是否相等的Matcher
    instanceOf() 检查给定的对象是X类型还是与X类型兼容

    notNullValue() + nullValue() 测试给定对象是否不是null,是否是null

静态方法matches()创建一个新的Matcher并返回它。

该Matcher是BaseMatcher类的匿名子类。JUnit文档指出,您应该始终扩展BasreMatcher,而不是自己实现Matcher。因此,如果将来将新方法添加到Matcher中,BaseMatcher可以实现它们。你的子类也会自动得到这些方法。这将避免破坏您的代码。

下面是如何使用这个自定义Matcher:

1
2
3
4
5
6
7
@Test
public void testThat() {
MyUnit myUnit = new MyUnit();

assertThat(myUnit.getTheSameObject(), matches("constant string"));

}