Java單元測試常用工具類小結
單元測試
單元測試是系統中非常基礎的功能,以功能的最小粒度進行功能測試,保證系統功能的正確行。
Assert
所屬類庫: JUnit library
類名: Assert
功能描述: 用以判斷結果是否符合預期
常用方法:
- assertTrue(String message, boolean condition)
- assertThat(String reason, T actual, Matcher<? super T> matcher)
- assertEquals(String message, Object expected, Object acutal)
由於Assert其中提供了大量的判斷方法,這裡就不再一一贅述,在需要之時進行查閱即可。
這裡以assertThat為例做一個簡要的分析:
其原始碼定義如下:
public static <T> void assertThat(T actual, Matcher<? super T> matcher) {
assertThat("", actual, matcher);
}
其中引數如下:
- T: 只是判斷的資料型別, 與第三個引數matcher中的T型別相同
- Matcher: 是hamcrest類庫中的Matcher介面,用來實現基本的判斷比較,稍後將針對Matcher進行簡要的介紹分析
- reason。自定義的描述下資訊,在判斷為失敗的情況下展示。
使用示例如下:
import org.junit.Assert;
import org.junit.Test;
import static org.hamcrest.number.OrderingComparison.greaterThan;
public class AssertDemo {
/**
* 檢查數字值需要大於10
*/
@Test
public void testAssert() {
Long count = 12l;
Assert.assertThat("Count is lower than 10", count, greaterThan(10l));
}
}
這裡的單元測試簡單用於測試count的值是否大於10,型別為Long。
Hamcrest介紹
官方站點: http://hamcrest.org/JavaHamcrest/distributables
在Spring Boot中的單元測試中,其依賴關係如下:
從其中可以看出,hamcrest存在兩個類庫,其中junit依賴的是hamcrest-core,包括在實際的單元測試中,同樣會碰到在類庫類庫中出現相同的方法。兩者的區別是什麼呢?
Hamcrest類庫進行了拆分,hamcrest-core包括最基本的matchers和抽象類以及建立這些matcher的工廠方法;主要用於構建其它的Matchers。類庫路徑: org.hamcrest.CoreMatchers。
hamcrest-library: 主要按照功能進行分組的Matcher,他們是可選的,擴充套件的Mather功能。
org.hamcrest.Matchers包含了core和library中兩者的功能。
如何來使用呢?
簡單起見,就直接將它們引入進來即可:
import static org.hamcrest.MatcherAssert.*;
import static org.hamcrest.Matchers.*;
所有的這些Matcher是可以彼此巢狀使用的。
Hamcrest用法
定義實體類:
@Data
@AllArgsConstructor
@NoArgsConstructor
static class Apple {
private Long id;
private String name;
@Override
public String toString() {
return id + "-" + name;
}
}
Core
- anything - always matches, true
- describedAs 定製失敗描述資訊的裝飾器
- is 等同於equalTo()
測試程式碼:
@Test
public void testCore() {
List<String> strs = Lists.newArrayList();
strs.add("abef");
strs.add("what it is");
//無論如何都是成功的
Assert.assertThat(strs, Matchers.anything());
List<String> tstrs = Lists.newArrayList();
tstrs.add("abef");
// 裝飾模式,定製化錯誤提示資訊
Assert.assertThat(strs, Matchers.describedAs("Custom Failure Information:%0", Matchers.hasItem("1abef"), "Array Item"));
}
注意這裡的decorateAs方法,其中使用的%0的位置佔位符。
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
- either(Matcher).or(Matcher)
- both(Matcher).and(Matcher)
使用程式碼示例:
@Test
public void testLogic() {
Apple apl = new Apple();
Apple apl2 = apl;
// allOf:如果所有匹配器都匹配才匹配
Assert.assertThat("What it is?", Matchers.allOf(Matchers.endsWith("?"), Matchers.startsWith("What")));
// anyOf:如果任何匹配器匹配就匹配
Assert.assertThat("What it is?", Matchers.anyOf(Matchers.endsWith("?"), Matchers.notNullValue()));
// not:如果包裝的匹配器不匹配器時匹配,反之亦然
Assert.assertThat("What it is?", Matchers.not(Matchers.endsWith("is")));
// is:如果包裝的匹配器匹配器時匹配,反之亦然
Assert.assertThat(apl, Matchers.is(apl2));
Assert.assertThat("What it is?", Matchers.is(Matchers.endsWith("is?")));
}
Object
- equalTo 測試 object 是否相等的,底層使用Object.equals
- hasToString 測試Object.toString
- instanceOf, isCompatibleType 判斷型別
- notNullValue, nullValue 判斷物件null
- sameInstance 判斷是否為同一個物件
使用示例:
@Test
public void testObject() {
Apple apl = new Apple(12l, "name1");
Apple apl2 = apl;
//判斷物件是否相等
Assert.assertThat(apl, Matchers.equalTo(apl2));
// has ToString
//測試toString()
Assert.assertThat(apl, Matchers.hasToString("12-name1"));
//InstanceOf
Assert.assertThat(apl, Matchers.instanceOf(Apple.class));
//NotnullValue
Assert.assertThat(apl, Matchers.notNullValue());
//NullValue
Assert.assertThat(null, Matchers.nullValue());
//same instance
Assert.assertThat(apl, Matchers.sameInstance(apl2));
}
Beans
- hasProperty 判斷Bean是否特定屬性
程式碼使用示例:
@Test
public void testBean() {
Apple apl = new Apple();
//check 其是否有屬性name
Assert.assertThat(apl, Matchers.hasProperty("name"));
}
Collections
這裡的集合是指Matcher集合,不是指資料。
- array Matcher資料匹配
- hasEntry, hasKey, hasValue, 檢查Map中是否含有an entry, key or value
- hasItem, hasItems,測試一個Collections是否含有元素
- hasItemInArray 檢查陣列中是否包含一個元素
- isIn(T t): 檢查是否在某個Colleciton之內
- arrayContainingInAnyOrder
- arrayContaining()
- arrayWithSize(int/Matcher): 陣列大小
- hasSize(int/Mathcer): Collection大小
使用示例:
@Test
public void testCollection() {
List<Apple> apples = Lists.newArrayList();
apples.add(new Apple(1l, "zhangsan"));
apples.add(new Apple(2l, "lisi"));
Apple[] aplArray = new Apple[]{new Apple(3l, "zhangsan"), new Apple(4l, "wangwu")};
Apple apl = new Apple(1l, "zhagnsan");
Apple testApl = apples.get(0);
String[] strArray = {"12", "34"};
//注意這裡只能是Object Array
Assert.assertThat(apples.toArray(aplArray), Matchers.array(Matchers.notNullValue(), Matchers.hasProperty( "name")));
Assert.assertThat(strArray, Matchers.array(Matchers.equalTo("12"), Matchers.equalTo("34")));
Map<String, String> dataMap = new HashMap();
dataMap.put("key1", "val1");
dataMap.put("key2", "val2");
Assert.assertThat(dataMap, Matchers.hasEntry("key1", "val1"));
Assert.assertThat(dataMap, Matchers.hasValue("val1"));
Assert.assertThat(dataMap, Matchers.hasKey("key1"));
}
@Test
public void testIterable() {
List<Apple> apples = Lists.newArrayList();
apples.add(new Apple(1l, "zhangsan"));
apples.add(new Apple(2l, "lisi"));
Apple apl = new Apple(1l, "zhangsan");
Apple apl1 = new Apple(2l, "lisi");
//檢查單個元素
Assert.assertThat(apples, Matchers.hasItem(apl));
//檢查多個元素
Assert.assertThat(apples, Matchers.hasItems(apl1,apl));
Apple[] aplArray = new Apple[2];
//陣列元素
Assert.assertThat(apples.toArray(aplArray), Matchers.hasItemInArray(apl));
//在Colleciton中
Assert.assertThat(apl, Matchers.isIn(apples));
}
Number
- closeTo 測試浮點數是否接近一個數字值
- greaterThan, greaterThanOrEqualTo, lessThan, lessThanOrEqualTo 檢查數字的大小
使用示例程式碼:
@Test
public void testNumber() {
// closeTo:測試浮點值接近給定的值
Assert.assertThat(1.5, Matchers.closeTo(1.0, 0.6));
// greaterThan, greaterThanOrEqualTo, lessThan, lessThanOrEqualTo:測試大於,小於
Assert.assertThat(1.0, Matchers.greaterThan(0.5));
Assert.assertThat(1.5, Matchers.lessThanOrEqualTo(1.5));
}
Text
- equalToIgnoringCase 檢查字串相等,忽略大小寫
- equalToIgnoringWhiteSpace 檢查字串相等,忽略空白字元
- containsString, endsWith, startsWith 檢查字串匹配
使用示例:
@Test
public void testText() {
// equalToIgnoringCase:測試字串相等忽略大小寫
Assert.assertThat("Hello world", Matchers.equalToIgnoringCase("hello world"));
// equalToIgnoringWhiteSpace:測試字串忽略空白
Assert.assertThat(" Hello world", Matchers.equalToIgnoringWhiteSpace("Helloworld"));
// containsString, endsWith, startsWith:測試字串匹配
Assert.assertThat("Hello world", Matchers.containsString("Hello"));
Assert.assertThat("Hello world", Matchers.startsWith("Hello"));
Assert.assertThat("Hello world", Matchers.endsWith("world"));
}
總結
這裡所有的這些方法在語言中都是有其他替代選擇,他們只是讓你閱讀起來更容易而已,更符合人的閱讀和理解習慣。
相關文章
- 測試 之Java單元測試、Android單元測試JavaAndroid
- Spring Boot之DAO層的單元測試小結Spring Boot
- java中的單元測試Java
- Java單元測試神器之MockitoJavaMockito
- Java單元測試技巧之PowerMockJavaMock
- 1.13-java單元測試junitJava
- 測試開發之單元測試-禪道結合ZTF驅動單元測試執行
- 單元測試:單元測試中的mockMock
- 鮑勃大爺:單元測試中單元是多小?
- 單元測試&反射機制(未完結)反射
- ABAP和Java SpringBoot的單元測試JavaSpring Boot
- java單元測試:unit testing best practicesJava
- 如何單元測試Java的private方法Java
- java 常用工具類Java
- Spring Boot單元測試之服務層測試總結Spring Boot
- Java中的單元測試與整合測試最佳實踐Java
- android單元測試遇到問題總結Android
- SpringBoot與單元測試JUnit的結合Spring Boot
- ABAP和Java的單元測試Unit TestJava
- Java Junit單元測試(入門必看篇)Java
- Java單元測試之JUnit 5快速上手Java
- 單元測試,只是測試嗎?
- 單元測試-【轉】論單元測試的重要性
- 金字塔測試原理:寫好單元測試的8個小技巧,一文總結
- SpringBoot單元測試Spring Boot
- python 單元測試Python
- iOS 單元測試iOS
- Flutter 單元測試Flutter
- 單元測試 Convey
- 單元測試真
- golang單元測試Golang
- 單元測試工具
- 前端單元測試前端
- 十五、單元測試
- Go單元測試Go
- 聊聊單元測試
- Spring Boot之單元測試用例總結Spring Boot
- 軟體工程單元測試作業總結軟體工程