Junit4X系列--hamcrest的使用
OK,在前面的一系列博客里面,我整理过了Assert类下面常用的断言方法,比如assertEquals等等,但是org.junit.Assert类下还有一个方法也用来断言,而且更加强大。这就是我们这里要这里的:
Assert的AssertThat()方法和Hamcrest匹配器
1,断言抛出的异常
package test.junit4test; import org.junit.Test; public class LinkinTest
{ @Test(expected=NullPointerException.class)
public void test()
{
String str = null;
System.out.println(str.toString());
}
}
package test.junit4test; import org.hamcrest.Matchers;
import org.junit.Assert;
import org.junit.Test; public class LinkinTest
{ @Test
public void test()
{
try
{
throw new Exception("吆西,这里应该抛出异常的呢。。。");
}
catch (Exception e)
{
Assert.assertThat(e.getMessage(), Matchers.containsString("吆西"));
}
}
}
2,现在让我们来认真的看下assertThat()和Hamcrest匹配器吧
Assert类的assertThat()方法源码:
public static <T> void assertThat(T actual, Matcher<? super T> matcher) {
assertThat("", actual, matcher);
}
上面的这个断言方法最后一个参数要传入一个matcher,这个方法是一个钩子,允许程序员自行扩展基本的断言,或者使用第三方的匹配器库。
使用Hamcrest要导入hamcrest-junit包的,注意这个包可不是junit4.12自带的那个hamcrest-core这个jar。
junit4.12自带hamcrest-core的依赖,我们来看下junit4.12的pom文件:
<dependencies>
<dependency>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest-core</artifactId>
<version>1.3</version>
</dependency>
</dependencies>
OK,那我们现在导入hamcrest-junit包,项目中pom文件如下:
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest-junit</artifactId>
<version>2.0.0.0</version>
<scope>test</scope>
</dependency>
</dependencies>
3,现在我们来看下Hamcrest的api
========================================================================================================================================================================================
A tour of common matchers
Hamcrest comes with a library of useful matchers. Here are some of the most important ones.
- Core
anything - always matches, useful if you don't care what the object under test is
describedAs - decorator to adding custom failure description
is - decorator to improve readability - see "Sugar", below
- Logical
allOf - matches if all matchers match, short circuits (like Java &&)
anyOf - matches if any matchers match, short circuits (like Java ||)
not - matches if the wrapped matcher doesn't match and vice versa
- Object
equalTo - test object equality using Object.equals
hasToString - test Object.toString
instanceOf, isCompatibleType - test type
notNullValue, nullValue - test for null
sameInstance - test object identity
- Beans
hasProperty - test JavaBeans properties
- Collections
array - test an array's elements against an array of matchers
hasEntry, hasKey, hasValue -
test a map contains an entry, key or value
hasItem, hasItems - test a collection contains
elements
hasItemInArray - test an array contains an element
- Number
closeTo - test floating point values are close to a given value
greaterThan, greaterThanOrEqualTo, lessThan, lessThanOrEqualTo -
test ordering
- Text
equalToIgnoringCase - test string equality ignoring case
equalToIgnoringWhiteSpace - test string equality ignoring differences in runs of whitespace
containsString, endsWith, startsWith -
test string matching
========================================================================================================================================================================================
OK,下面我写了一个例子,让我们来看下Hamcrest匹配器的使用。
package org.linkinpark.junit.testjunit;
import static org.junit.Assert.assertThat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.hamcrest.Matchers;
import org.junit.Before;
import org.junit.Test;
public class LinkinTest
{
private Linkin linkin;
private Linkin linkin1;
private Linkin linkin2;
private List<Linkin> list = new ArrayList<>(3);
private Map<String, Linkin> map = new HashMap<>();
String[] strArray = { "1", "2" };
@Before
public void setUp()
{
linkin = new Linkin();
linkin1 = new Linkin();
linkin2 = linkin1;
list.add(linkin);
list.add(linkin1);
list.add(linkin2);
map.put("linkin", linkin);
map.put("linkin1", linkin1);
map.put("linkin2", linkin2);
}
@SuppressWarnings("unchecked")
@Test
public void test() throws Exception
{
/******************* 对象相关方法 ********************************/
// equalTo:判断2个对象是否相等,使用Object.equals方法
assertThat(linkin1, Matchers.equalTo(linkin2));
// hasToString:判断一个对象的toString方法
assertThat(linkin, Matchers.hasToString("Linkin [name=null, age=null]"));
// instanceOf:判断对象是否为某个类的实例对象
assertThat(linkin, Matchers.instanceOf(Linkin.class));
// notNullValue,nullValue:判断对象是否为null值
assertThat(null, Matchers.nullValue());
assertThat(linkin, Matchers.notNullValue());
// sameInstance: 测试2个对象是否同一个实例
assertThat(linkin1, Matchers.sameInstance(linkin2));
/******************* javaBean相关方法 ****************************/
assertThat(linkin, Matchers.hasProperty("name"));
/******************* 集合相关方法 ********************************/
assertThat(strArray, Matchers.array(Matchers.equalTo("1"), Matchers.equalTo("2")));
// hasEntry, hasKey, hasValue:测试一个Map包含一个实体,键或者值
assertThat(map, Matchers.hasEntry("linkin", linkin));
assertThat(map, Matchers.hasKey("linkin"));
assertThat(map, Matchers.hasValue(linkin));
// hasItem, hasItems:测试一个集合包含一个元素
assertThat(list, Matchers.hasItem(linkin));
assertThat(list, Matchers.hasItems(linkin, linkin1));
// hasItemInArray:测试一个数组包含一个元素
assertThat(strArray, Matchers.hasItemInArray("1"));
// in:测试一个对象在一个集合中
assertThat(linkin, Matchers.in(list));
/******************* 数字相关方法 ********************************/
// closeTo:测试浮点值接近给定的值
assertThat(1.5, Matchers.closeTo(1.0, 0.6));
// greaterThan, greaterThanOrEqualTo, lessThan, lessThanOrEqualTo:测试大于,小于
assertThat(1.0, Matchers.greaterThan(0.5));
assertThat(1.5, Matchers.lessThanOrEqualTo(1.5));
/******************* 文本相关方法 ********************************/
// equalToIgnoringCase:测试字符串相等忽略大小写
assertThat("LinkinPark", Matchers.equalToIgnoringCase("linkinpark"));
// equalToIgnoringWhiteSpace:测试字符串忽略空白
assertThat(" LinkinPark111", Matchers.equalToIgnoringWhiteSpace("LinkinPark111"));
// containsString, endsWith, startsWith:测试字符串匹配
assertThat("LinkinPark", Matchers.containsString("Lin"));
assertThat("LinkinPark", Matchers.startsWith("Lin"));
assertThat("LinkinPark", Matchers.endsWith("Park"));
/******************* 逻辑相关方法 ********************************/
// allOf:如果所有匹配器都匹配才匹配
assertThat("LinkinPark", Matchers.allOf(Matchers.endsWith("Park"), Matchers.startsWith("Lin")));
// anyOf:如果任何匹配器匹配就匹配
assertThat("LinkinPark", Matchers.anyOf(Matchers.endsWith("P22ark"), Matchers.notNullValue()));
// not:如果包装的匹配器不匹配器时匹配,反之亦然
assertThat("LinkinPark", Matchers.not(Matchers.endsWith("P22ark")));
// is:如果包装的匹配器匹配器时匹配,反之亦然
assertThat(linkin1, Matchers.is(linkin2));
assertThat("LinkinPark", Matchers.is(Matchers.endsWith("Park")));
}
}
关于上面的代码解释一下,就代码的可读性来说,我没有静态导入Matchers类下的所有方法,所以代码充斥着大量的该类打点。这里只是我第一次使用Hamcrest匹配器,所以方便我自己调方法才这么写的。以后如果经常用到一些类的静态方法的话那么建议大家都静态导出。比如说使用Assert类调用它里面那些静态方法就应该静态导入。
4,扩展Hamcrest的Matcher接口自定义匹配器。
如果内置的断言或者Hamcrest匹配器不足以表达我们的意图的时候,我们可以自己来扩展。我们自己实现自己的匹配器,要实现Hamcrest的Matcher接口。
这里我举个例子,现在我自定义一个匹配器,来检验一个字符串必须包含“Linkin”这个字符串,代码如下:
package org.linkinpark.junit.testjunit;
import org.hamcrest.BaseMatcher;
import org.hamcrest.Description;
import org.hamcrest.Matcher;
import org.junit.Assert;
import org.junit.Test;
public class LinkinTest
{
@Test
public void test() throws Exception
{
Assert.assertThat("LinkinPark", isLinkinStr());
}
public Matcher<String> isLinkinStr()
{
return new BaseMatcher<String>()
{
@Override
public boolean matches(Object item)
{
if (!(item instanceof String))
{
return false;
}
return ((String) item).contains("Linkin");
}
@Override
public void describeTo(Description description)
{
description.appendText("字符串必须包含Linkin这个单词。。。");
}
};
}
}
OK,junit窗口绿条没问题,如果一个字符串不包含“Linkin”这个单词,那么测试就会报错,我们来看下junit窗口下的显示情况。

Assert类的assertThat()方法源码:
public static <T> void assertThat(T actual, Matcher<? super T> matcher) {
assertThat("", actual, matcher);
}
使用Hamcrest要导入hamcrest-junit包的,注意这个包可不是junit4.12自带的那个hamcrest-core这个jar。
<dependencies>
<dependency>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest-core</artifactId>
<version>1.3</version>
</dependency>
</dependencies>
OK,那我们现在导入hamcrest-junit包,项目中pom文件如下:
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest-junit</artifactId>
<version>2.0.0.0</version>
<scope>test</scope>
</dependency>
</dependencies>
3,现在我们来看下Hamcrest的api
A tour of common matchers
Hamcrest comes with a library of useful matchers. Here are some of the most important ones.
- Core
anything- always matches, useful if you don't care what the object under test isdescribedAs- decorator to adding custom failure descriptionis- decorator to improve readability - see "Sugar", below
- Logical
allOf- matches if all matchers match, short circuits (like Java &&)anyOf- matches if any matchers match, short circuits (like Java ||)not- matches if the wrapped matcher doesn't match and vice versa
- Object
equalTo- test object equality using Object.equalshasToString- test Object.toStringinstanceOf,isCompatibleType- test typenotNullValue,nullValue- test for nullsameInstance- test object identity
- Beans
hasProperty- test JavaBeans properties
- Collections
array- test an array's elements against an array of matchershasEntry,hasKey,hasValue-
test a map contains an entry, key or valuehasItem,hasItems- test a collection contains
elementshasItemInArray- test an array contains an element
- Number
closeTo- test floating point values are close to a given valuegreaterThan,greaterThanOrEqualTo,lessThan,lessThanOrEqualTo-
test ordering
- Text
equalToIgnoringCase- test string equality ignoring caseequalToIgnoringWhiteSpace- test string equality ignoring differences in runs of whitespacecontainsString,endsWith,startsWith-
test string matching
========================================================================================================================================================================================
OK,下面我写了一个例子,让我们来看下Hamcrest匹配器的使用。
package org.linkinpark.junit.testjunit; import static org.junit.Assert.assertThat; import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map; import org.hamcrest.Matchers;
import org.junit.Before;
import org.junit.Test; public class LinkinTest
{
private Linkin linkin;
private Linkin linkin1;
private Linkin linkin2;
private List<Linkin> list = new ArrayList<>(3);
private Map<String, Linkin> map = new HashMap<>();
String[] strArray = { "1", "2" }; @Before
public void setUp()
{
linkin = new Linkin();
linkin1 = new Linkin();
linkin2 = linkin1;
list.add(linkin);
list.add(linkin1);
list.add(linkin2);
map.put("linkin", linkin);
map.put("linkin1", linkin1);
map.put("linkin2", linkin2);
} @SuppressWarnings("unchecked")
@Test
public void test() throws Exception
{
/******************* 对象相关方法 ********************************/
// equalTo:判断2个对象是否相等,使用Object.equals方法
assertThat(linkin1, Matchers.equalTo(linkin2));
// hasToString:判断一个对象的toString方法
assertThat(linkin, Matchers.hasToString("Linkin [name=null, age=null]"));
// instanceOf:判断对象是否为某个类的实例对象
assertThat(linkin, Matchers.instanceOf(Linkin.class));
// notNullValue,nullValue:判断对象是否为null值
assertThat(null, Matchers.nullValue());
assertThat(linkin, Matchers.notNullValue());
// sameInstance: 测试2个对象是否同一个实例
assertThat(linkin1, Matchers.sameInstance(linkin2)); /******************* javaBean相关方法 ****************************/
assertThat(linkin, Matchers.hasProperty("name")); /******************* 集合相关方法 ********************************/
assertThat(strArray, Matchers.array(Matchers.equalTo("1"), Matchers.equalTo("2")));
// hasEntry, hasKey, hasValue:测试一个Map包含一个实体,键或者值
assertThat(map, Matchers.hasEntry("linkin", linkin));
assertThat(map, Matchers.hasKey("linkin"));
assertThat(map, Matchers.hasValue(linkin));
// hasItem, hasItems:测试一个集合包含一个元素
assertThat(list, Matchers.hasItem(linkin));
assertThat(list, Matchers.hasItems(linkin, linkin1));
// hasItemInArray:测试一个数组包含一个元素
assertThat(strArray, Matchers.hasItemInArray("1"));
// in:测试一个对象在一个集合中
assertThat(linkin, Matchers.in(list)); /******************* 数字相关方法 ********************************/
// closeTo:测试浮点值接近给定的值
assertThat(1.5, Matchers.closeTo(1.0, 0.6));
// greaterThan, greaterThanOrEqualTo, lessThan, lessThanOrEqualTo:测试大于,小于
assertThat(1.0, Matchers.greaterThan(0.5));
assertThat(1.5, Matchers.lessThanOrEqualTo(1.5)); /******************* 文本相关方法 ********************************/
// equalToIgnoringCase:测试字符串相等忽略大小写
assertThat("LinkinPark", Matchers.equalToIgnoringCase("linkinpark"));
// equalToIgnoringWhiteSpace:测试字符串忽略空白
assertThat(" LinkinPark111", Matchers.equalToIgnoringWhiteSpace("LinkinPark111"));
// containsString, endsWith, startsWith:测试字符串匹配
assertThat("LinkinPark", Matchers.containsString("Lin"));
assertThat("LinkinPark", Matchers.startsWith("Lin"));
assertThat("LinkinPark", Matchers.endsWith("Park")); /******************* 逻辑相关方法 ********************************/
// allOf:如果所有匹配器都匹配才匹配
assertThat("LinkinPark", Matchers.allOf(Matchers.endsWith("Park"), Matchers.startsWith("Lin")));
// anyOf:如果任何匹配器匹配就匹配
assertThat("LinkinPark", Matchers.anyOf(Matchers.endsWith("P22ark"), Matchers.notNullValue()));
// not:如果包装的匹配器不匹配器时匹配,反之亦然
assertThat("LinkinPark", Matchers.not(Matchers.endsWith("P22ark")));
// is:如果包装的匹配器匹配器时匹配,反之亦然
assertThat(linkin1, Matchers.is(linkin2));
assertThat("LinkinPark", Matchers.is(Matchers.endsWith("Park")));
} }
关于上面的代码解释一下,就代码的可读性来说,我没有静态导入Matchers类下的所有方法,所以代码充斥着大量的该类打点。这里只是我第一次使用Hamcrest匹配器,所以方便我自己调方法才这么写的。以后如果经常用到一些类的静态方法的话那么建议大家都静态导出。比如说使用Assert类调用它里面那些静态方法就应该静态导入。
package org.linkinpark.junit.testjunit; import org.hamcrest.BaseMatcher;
import org.hamcrest.Description;
import org.hamcrest.Matcher;
import org.junit.Assert;
import org.junit.Test; public class LinkinTest
{ @Test
public void test() throws Exception
{
Assert.assertThat("LinkinPark", isLinkinStr());
} public Matcher<String> isLinkinStr()
{
return new BaseMatcher<String>()
{ @Override
public boolean matches(Object item)
{
if (!(item instanceof String))
{
return false;
}
return ((String) item).contains("Linkin");
} @Override
public void describeTo(Description description)
{
description.appendText("字符串必须包含Linkin这个单词。。。");
} };
} }
OK,junit窗口绿条没问题,如果一个字符串不包含“Linkin”这个单词,那么测试就会报错,我们来看下junit窗口下的显示情况。
Junit4X系列--hamcrest的使用的更多相关文章
- junit4X系列--Assert与Hamcrest
原文出处:http://www.blogjava.net/DLevin/archive/2012/05/12/377960.html.感谢作者无私分享 到目前,JUnit4所有的核心源码都已经讲解过了 ...
- junit4X系列--Runner解析
前面我整理了junit38系列的源码,那junit4X核心代码也基本类似.这里我先转载一些关于junit4X源码解析的好文章.感谢原作者的分享.原文地址:http://www.blogjava.net ...
- junit4X系列--Exception
原文出处:http://www.blogjava.net/DLevin/archive/2012/11/02/390684.html.感谢作者的无私分享. 说来惭愧,虽然之前已经看过JUnit的源码了 ...
- junit4X系列--Rule
原文出处:http://www.blogjava.net/DLevin/archive/2012/05/12/377955.html.感谢作者的无私分享. 初次用文字的方式记录读源码的过程,不知道怎么 ...
- junit4X系列源码--Junit4 Runner以及test case执行顺序和源代码理解
原文出处:http://www.cnblogs.com/caoyuanzhanlang/p/3534846.html.感谢作者的无私分享. 前一篇文章我们总体介绍了Junit4的用法以及一些简单的测试 ...
- junit4X系列源码--总体介绍
原文出处:http://www.cnblogs.com/caoyuanzhanlang/p/3530267.html.感谢作者的无私分享. Junit是一个可编写重复测试的简单框架,是基于Xunit架 ...
- junit4X系列--Builder、Request与JUnitCore
原文出处:http://www.blogjava.net/DLevin/archive/2012/05/12/377957.html.感谢作者的无私分享. 初次用文字的方式记录读源码的过程,不知道怎么 ...
- junit4X系列--Statement
原文出处:http://www.blogjava.net/DLevin/archive/2012/05/11/377954.html.感谢作者的无私分享. 初次用文字的方式记录读源码的过程,不知道怎么 ...
- junit测试延伸--方法的重复测试
在实际编码测试中,我们有的时候需要对一个方法进行多次测试,那么怎么办呢?这个问题和测试套件解决的方案一样,我们总不能不停的去右键run as,那怎么办呢?还好伟大的junit帮我们想到了. OK,现在 ...
随机推荐
- 巧用CSS实现宝马LOGO
某天突然遇到一个有趣的面试题,需用CSS实现一个宝马的Logo,第一反应就是这不是老生常谈的八卦图的小变形吗,只需用伪元素就可轻易的实现啦,但是细看要求说只能在一个标签里写样式,所以呜呜呜...请教下 ...
- Java 写三角形 空心三角形 菱形 空心菱形
闲来无事,练习了一下Java基础中的循环语句.练习循环语句,当然少不了,用*打印出来三角形.空心三角形.菱形等这样的几何图形. 粗心大意,失误两次: 一.三角形 遇到一些小问题: 二.金字塔 由于三角 ...
- Caused by: org.xml.sax.SAXParseException; systemId: file:/home/hadoop/hive-0.12.0/conf/hive-site.xml; lineNumber: 5; columnNumber: 2; The markup in the document following the root element must be well
1:Hive安装的过程(Hive启动的时候报的错误),贴一下错误,和为什么错,以及解决方法: [root@master bin]# ./hive // :: INFO Configuration.de ...
- centos 虚拟机桥接
/etc/sysconfig/network-scripts/ifcfg-eth0 配置文件 vi ifcfg-eth0 DEVICE=eth0HWADDR=00:0C:29:B8:B5:65TYPE ...
- 闲来无事,把node又拾起来看看
处在国企单位,整天闲的要死要死的,民族的花朵都快枯萎了 哎呀呀,打起精神.......早睡早起,多看书...开始进入苦读状态,苦练武功,争取有朝一日报效祖国...哈哈 开玩笑的 开始看书吧 记得N ...
- AJAX的写法
AJAX可以说是前端开发必须要会的技术.AJAX是异步的javascript and xml.是他们技术的合称. 1.原生写ajax.很多小伙伴在会了jQuery后,将原生都忘记了,所以原生我还是要在 ...
- 解决前端开发sublime text 3编辑器无法安装插件的问题
今天在笔记本电脑上安装了个sublime,但是却出现无法装插件的问题.于是稍微在网上查了些资料,并试验了一番,写了如下文章. 安装插件的步骤: 弹出 选中install package 如果出现如下问 ...
- Flask源码流程剖析
在此之前需要先知道类和方法,个人总结如下: 1.对象是类创建,创建对象时候类的__init__方法自动执行,对象()执行类的 __call__ 方法 2.类是type创建,创建类时候type的__i ...
- 连接WiFi工具类
public class WifiConnect { WifiManager wifiManager; // 构造函数 public WifiConnect(WifiManager wifiManag ...
- STL中的nth_element()方法的使用
STL中的nth_element()方法的使用 通过调用nth_element(start, start+n, end) 方法可以使第n大元素处于第n位置(从0开始,其位置是下标为 n的元素),并且比 ...