JUnit的好搭档-Hamcrest
一、Hamcrest简介
Hamcrest是一个用于编写匹配器(matcher)对象的框架,允许以声明方式定义“匹配(match)”规则。它可以与JUnit框架配合使用,使断言可读更高,更加灵活(例如判断数组、集合、map中的内容等)。
Hamcrest支持多种语言,本文只使用JAVA语言。Hamcrest官网:http://hamcrest.org/
二、Java Hamcrest 常用匹配器
@Test public void testAssertThatWithHamcrest() { /** * 核心: */ //anything:总是匹配,如果你不关心测试下的对象是什么是有用的 assertThat("随便是个啥", anything("总是匹配就完事了")); //describedAs:添加一个定制的失败表述装饰器 assertThat("zs", describedAs("自定义故障描述",equalTo("zs"))); //is:改进可读性装饰器 ,底层is(equalTo(value)) assertThat("zs",is("zs")); /** * 逻辑: */ //allOf:所有匹配器都匹配才匹配,相当于 && assertThat("张三", allOf(startsWith("张"), containsString("三"))); //anyOf:任何匹配器匹配就匹配,相当于 || assertThat("张三",anyOf(startsWith("李"),containsString("三"))); // not:包装的匹配器不匹配器时匹配,相当于与取反 assertThat("tom",not("lucy")); /** * 对象: */ //equalTo:测试对象相等使用Object.equals方法 assertThat("foo", equalTo("foo")); //hasToString:测试Object.toString方法 assertThat(true, hasToString(equalTo("true"))); //instanceOf, typeCompatibleWith:测试类型 assertThat("string", instanceOf(String.class)); assertThat(Integer.class, typeCompatibleWith(Number.class)); //notNullValue, nullValue:测试null assertThat(null,nullValue()); assertThat("",notNullValue()); //sameInstance:测试对象实例 Integer number = new Integer(200); assertThat(number,sameInstance(number)); /** * Beans: */ @Data class MyClass{ private String name; } //hasProperty:测试JavaBeans属性 assertThat(new MyClass(),hasProperty("name")); /** * 集合: */ //array:测试一个数组元素,每一项是否匹配 assertThat(new Integer[]{1,2,3}, is(array(equalTo(1), equalTo(2), equalTo(3)))); //hasEntry, hasKey, hasValue :测试一个Map包含一个实体,键或者值 Map<String,Integer> map = new HashMap<>(); map.put("张三",23); map.put("李四",24); assertThat(map,hasEntry("张三",23)); assertThat(map,hasKey("李四")); assertThat(map,hasValue(23)); //hasItem, hasItems:测试一个集合包含一个元素 assertThat(Arrays.asList("foo", "bar"),hasItem(startsWith("ba"))); assertThat(Arrays.asList("foo", "bar", "baz"), hasItems(endsWith("z"), endsWith("o"))); //hasItemInArray:测试一个数组包含一个元素 assertThat(new String[] {"foo", "bar"}, hasItemInArray(startsWith("ba"))); /** * 数字: */ // closeTo:测试浮点值接近给定的值,该匹配器在+/-error范围内匹配 assertThat(1.03, is(closeTo(1.0, 0.04))); //greaterThan, greaterThanOrEqualTo, lessThan, lessThanOrEqualTo :测试次序 assertThat(2, greaterThan(1)); assertThat(1, greaterThanOrEqualTo(1)); assertThat(1, lessThan(2)); assertThat(1, lessThanOrEqualTo(1)); /** * 文本: */ //equalToIgnoringCase:测试字符串相等忽略大小写 assertThat("Foo", equalToIgnoringCase("FOO")); //equalToIgnoringWhiteSpace:测试字符串忽略空白 assertThat(" my\tfoo bar ", equalToIgnoringWhiteSpace(" my foo bar")); //containsString, endsWith, startsWith:测试字符串匹配 assertThat("myStringOfNote", containsString("ring")); assertThat("myStringOfNote", endsWith("Note")); assertThat("myStringOfNote", startsWith("my")); }
三、自定义匹配器
示例代码:
import org.hamcrest.Description; import org.hamcrest.Matcher; import org.hamcrest.TypeSafeMatcher; /** * 自定义匹配器,判断年龄范围在[1,200]返回true * 1、继承TypeSafeMatcher并指定泛型 * 2、重写matchesSafely、describeTo方法 * 3、提供外部调用的静态方法 */ public class IsNormalAgeRange extends TypeSafeMatcher<Integer> { @Override public boolean matchesSafely(Integer number) { return number >=1 && number <=200; } @Override public void describeTo(Description description) { description.appendText("need to be within [1,200]"); } public static Matcher normalAgeRange() { return new IsNormalAgeRange(); } }
测试:
@Test public void testMyMatcher() { assertThat(100, IsNormalAgeRange.normalAgeRange()); }