hamcrest 로 가독성있는 jUnit Test Case 만들기
다양한 조건의 Match rule 을 손쉽게 작성하고 테스트 할 수 있는 library로 jUnit 이나 Mokoto 와 연계하여 사용할 수 있다.
예로 다음과 같은 jUnit assert 조건이 있다고 생각해 보자.
assertEquals(theBiscuit, myBiscuit); ;
JAVA
이 구문은 아래와 같이 is 나 euqalTo 를 사용해서 더 가독성있게 바꿀수 있다.(3가지 모두 동일한 의미)
assertThat(theBiscuit, equalTo(myBiscuit));
assertThat(theBiscuit, is(equalTo(myBiscuit)));
assertThat(theBiscuit, is(myBiscuit));
JAVA
늘 assert () 호출 조건이 헷갈렸다면 hamcrest 로 더 읽기 쉬운 테스트 코드를 작성할 수 있다.
설치
gradle
build.gradle 에 다음 구문을 추가한다.
dependencies {
testImplementation 'org.hamcrest:hamcrest:2.2'
}
CODE
Maven Pom
<dependency>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest</artifactId>
<version>2.2</version>
<scope>test</scope>
</dependency>
XML
Matchers
기본적으로 다양한 Matcher 가 제공되며 중요한 Matcher들은 다음과 같다.
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
import static org.hamcrest.Matchers.anything;
import static org.hamcrest.Matchers.notNullValue;
import static org.hamcrest.Matchers.nullValue;
import static org.junit.Assert.assertThat;
import static org.hamcrest.Matchers.is;
// null 을 기대하는데 null 이므로 성공
@Test
public void nullTest() {
String str = null;
assertThat(str, is(nullValue()));
}
// notnull 을 기대하는데 null 이므로 실패
@Test
public void notNullTest() {
String str = null;
assertThat(str, is(notNullValue()));
}
// 또는 not 을 사용해도 됨
String str = null;
assertThat(str, not(notNullValue()));
assertThat(str, not(nullValue()));
CODE
Objects
equalTo - test object equality using Object.equals
- hasToString - test Object.toString
- instanceOf, isCompatibleType - test type
- notNullValue, nullValue - test for null
- sameInstance - test object identity
import static org.hamcrest.Matchers.instanceOf;
@Test
public void instanceOfTest() {
HashMap<String, String> map1 = new HashMap<String, String>();
// instance 가 다르므로 실패
assertThat(map1, instanceOf(String.class));
}
CODE
Numbers
- closeTo - test floating point values are close to a given value
- greaterThan, greaterThanOrEqualTo, lessThan, lessThanOrEqualTo - test ordering
import static org.hamcrest.Matchers.lessThan;
import static org.hamcrest.Matchers.lessThanOrEqualTo;
import static org.hamcrest.Matchers.greaterThan;
import static org.hamcrest.Matchers.greaterThanOrEqualTo;
assertThat(2, greaterThan(1));
assertThat(1, greaterThanOrEqualTo(1));
assertThat(0, lessThan(1));
assertThat(0, lessThanOrEqualTo(1));
CODE
Beans
- hasProperty - test JavaBeans properties
property 에 대한 getter, setter 중 하나만 있으면 성공
import static org.hamcrest.Matchers.hasProperty;
import static org.junit.Assert.assertThat;
// hasProperty 용
private String myProperty;
public void setMyProperty(String property) {
this.property = property;
}
// 위에 myProperty가 있으므로 성공
@Test
public void propertyTest() {
assertThat(this, hasProperty("myProperty"));
}
CODE
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
@Test
public void test() {
Map<String, String> map1 = new HashMap<String, String>();
map1.put("foo1", "bar1");
map1.put("foo2", "bar2");
assertThat(map1, IsMapContaining.hasKey("foo1"));
assertThat(map1, IsMapContaining.hasEntry("foo1", "bar1"));
assertThat(map1, IsMapContaining.hasValue("bar1"));
}
CODE
Text
- equalToIgnoringCase - test string equality ignoring case
- equalToIgnoringWhiteSpace - test string equality ignoring differences in runs of whitespace
- containsString, endsWith, startsWith - test string matching
import static org.hamcrest.Matchers.equalToIgnoringCase;
import static org.hamcrest.Matchers.equalToIgnoringWhiteSpace;
//성공
assertThat("Spring", equalToIgnoringCase("spring"));
// 성공. 문자열 앞뒤의 공백만 무시하니 주의.
assertThat("Spring Framework 3.2", equalToIgnoringWhiteSpace (" Spring Framework 3.2 "));
// 성공
assertThat("Spring Framework 3.2", containsString("Framework"));
CODE
Ref
- https://github.com/hamcrest/JavaHamcrest
- https://code.google.com/p/hamcrest/wiki/Tutorial
junit 4.11 Release note - https://github.com/junit-team/junit/blob/master/doc/ReleaseNotes4.11.md
- http://junit.sourceforge.net/javadoc/org/junit/Assert.html