hamcrest 로 가독성있는 jUnit Test Case 만들기
다양한 조건의 Match rule 을 손쉽게 작성하고 테스트 할 수 있는 library로 jUnit 이나 Mokoto 와 연계하여 사용할 수 있다.
예로 다음과 같은 jUnit assert 조건이 있다고 생각해 보자.
assertEquals(theBiscuit, myBiscuit); ;
이 구문은 아래와 같이 is 나 euqalTo 를 사용해서 더 가독성있게 바꿀수 있다.(3가지 모두 동일한 의미)
assertThat(theBiscuit, equalTo(myBiscuit)); assertThat(theBiscuit, is(equalTo(myBiscuit))); assertThat(theBiscuit, is(myBiscuit));
늘 assert () 호출 조건이 헷갈렸다면 hamcrest 로 더 읽기 쉬운 테스트 코드를 작성할 수 있다.
설치
gradle
build.gradle 에 다음 구문을 추가한다.
dependencies { testImplementation 'org.hamcrest:hamcrest:2.2' }
Maven Pom
<dependency> <groupId>org.hamcrest</groupId> <artifactId>hamcrest</artifactId> <version>2.2</version> <scope>test</scope> </dependency>
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()));
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)); }
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));
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")); }
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")); }
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"));
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