上一節所使用的 assert 可以提供簡單的驗證,但是有時候測試並不是那麼的單純,這時候就需要其他工具了。Hamcrest 是一套輔助測試的 Library,提供了許多方便的 API 來測試較複雜的測試案例。
gradle 設定
testCompile 'org.hamcrest:hamcrest-all:1.3'
AssertThat
Hamcrest 的驗證都是使用 AssertThat(actual, matcher) 來做驗證,與上一節的 assert(expect, actual) 順序相反,但是卻相對上比較好閱讀,請看以下範例:
@Test
public void one_add_one_equals_two(){
int expect = 2;
int actual = 1 + 1;
assertEquals(expect, actual);
}
如果使用 AssertThat 就會變成這樣:
@Test
public void one_add_one_equals_two(){
int expect = 2;
int actual = 1 + 1;
MatcherAssert.assertThat(actual, Matchers.is(expect));
}
好像變複雜了?再看看以下範例
@Test
public void array_hasItems_element_1_5(){
List<Integer> integerArray = Arrays.asList(1, 2, 3, 5);
MatcherAssert.assertThat(integerArray, Matchers.hasItems(1, 5));
}
在這案例中如果不使用 Hamcrest 會相對的不容易測試,如果再加上 import static 可以更加好閱讀:
import static org.hamcrest.Matchers.hasItems;
import static org.hamcrest.MatcherAssert.assertThat;
...
@Test
public void array_hasItems_element_1_5(){
List<Integer> integerArray = Arrays.asList(1, 2, 3, 5);
assertThat(integerArray, hasItems(1, 5));
}
其他API
以下列出幾個簡單的範例,詳細說明請參考官方文件
1. 字串比對
@Test
public void test_stringCompare(){
assertThat("StringCompare", startsWith("String"));
assertThat("StringCompare", endsWith("Compare"));
assertThat("StringCompare", containsString("ingCom"));
}
2. iterable 相關 API
@Test
public void test_iterable(){
List<Integer> integerArray = Arrays.asList(1, 2, 3, 5);
assertThat(integerArray, contains(1, 2, 3, 5));
assertThat(integerArray, hasItem(1));
assertThat(integerArray, containsInAnyOrder(5, 3, 1, 2));
assertThat(integerArray, hasSize(4));
}
3. map 相關 API
@Test
public void test_map(){
Map<String, String> stringMap = new HashMap<>();
stringMap.put("key1", "value1");
stringMap.put("key2", "value2");
stringMap.put("key3", "value3");
assertThat(stringMap, hasKey("key1"));
assertThat(stringMap, hasValue("value2"));
assertThat(stringMap, hasEntry("key3", "value3"));
}
4. 條件相關 API
@Test
public void test_condition(){
assertThat("Condition", allOf(startsWith("Con"), containsString("iti")));
assertThat("Condition", anyOf(startsWith("Cond"), startsWith("iti")));
assertThat("Condition", not(startsWith("tion")));
}