Junit4X系列--hamcrest的使用
来源:互联网 发布:阿里云国际 信用卡 编辑:程序博客网 时间:2024/06/05 03:19
OK,在前面的一系列博客里面,我整理过了Assert类下面常用的断言方法,比如assertEquals等等,但是org.junit.Assert类下还有一个方法也用来断言,而且更加强大。这就是我们这里要这里的:
Assert的AssertThat()方法和Hamcrest匹配器
1,断言抛出的异常
明显的,有的时候我们想测试我们的代码在某种情况下抛出异常。比如说对于无效输入,我们希望代码抛出IllegalArgumentException。前面我也已经说过了,可以使用Test注解的一个expected属性来遇见我们抛出的异常。代码如下:
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());}}
这是一种检查异常的简洁方式。但是有时候我们想更加具体的了解抛出的具体异常。考虑如下情景:现在我们除了想知道我们抛出的异常属于那种类型,我们还想检查抛出的异常中“message”中携带的信息。那么怎么办呢?
那么没办法,让我们返回到古老的try和catch吧。然后在catch块中我们来使用Assert类的assertThat()方法和强大的Hamcrest匹配器来处理吧。代码如下:
package test.junit4test;import org.hamcrest.Matchers;import org.junit.Assert;import org.junit.Test;public class LinkinTest{@Testpublic 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 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" };@Beforepublic 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")@Testpublic 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{@Testpublic void test() throws Exception{Assert.assertThat("LinkinPark", isLinkinStr());}public Matcher<String> isLinkinStr(){return new BaseMatcher<String>(){@Overridepublic boolean matches(Object item){if (!(item instanceof String)){return false;}return ((String) item).contains("Linkin");}@Overridepublic 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); }
上面的这个断言方法最后一个参数要传入一个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>
<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" };@Beforepublic 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")@Testpublic 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{@Testpublic void test() throws Exception{Assert.assertThat("LinkinPark", isLinkinStr());}public Matcher<String> isLinkinStr(){return new BaseMatcher<String>(){@Overridepublic boolean matches(Object item){if (!(item instanceof String)){return false;}return ((String) item).contains("Linkin");}@Overridepublic void describeTo(Description description){description.appendText("字符串必须包含Linkin这个单词。。。");}};}}
OK,junit窗口绿条没问题,如果一个字符串不包含“Linkin”这个单词,那么测试就会报错,我们来看下junit窗口下的显示情况。
OK,实际编码中一般不会自己来创建自己的匹配器,了解下好了。下一篇我开始整理junit4X的规则和运行器。
0 0
- Junit4X系列--hamcrest的使用
- junit4X系列--Assert与Hamcrest
- Junit4--hamcrest的使用
- junit4X系列--Runner解析
- junit4X系列--Statement
- junit4X系列--Rule
- junit4X系列--Exception
- junit4X系列源码--总体介绍
- Hamcrest使用
- 学习junit和hamcrest的使用
- 使用Hamcrest增强JUnit的测试能力
- 使用hamcrest增强testng的测试能力
- junit4X系列--Builder、Request与JUnitCore
- JUnit: Hamcrest 使用
- JUnit: Hamcrest使用
- Junit hamcrest使用
- Junit中使用hamcrest
- 使用hamcrest错误
- ACCESS网站示例-连载-提示类文件
- bzoj1212 L语言 递推&Tire
- 表格SQL参数定义
- 身为程序员的你需要学习的15种编程语言
- 下标
- Junit4X系列--hamcrest的使用
- 引导用户主动生产优质内容
- Android蓝牙开发全面总结
- ubuntu启动级别
- 学习两个程序员结对编程的故事
- A. Wet Shark and Odd and Even
- 表格字段定义
- 产品运营需要具备哪些技能
- ubuntu修改计算机名