Clean Software/Testing

Hamcrest (읽기 쉬운 JUnit Test 코드 작성하기)

728x90
반응형

Hamcrest 란?

더보기

Hamcrest 란? 위키백과

Hamcrest는 Java 프로그래밍 언어로 소프트웨어 테스트 작성을 지원하는 프레임 워크입니다.

사용자 지정 assert  matcher생성을 지원하여 일치 규칙을 선언적으로 정의 할 수 있습니다.

이러한 matcher는 JUnit 및 jMock과 같은 단위 테스트 프레임 워크에서 사용됩니다.

Junit에서 Hamcrest matcher를 사용하려면 assertThat 문 뒤에 하나 또는 여러 개의 matchers를 사용한다.

assertThat(T actual, Matcher<T> matcher)

 

가령 아래의 식을

// Junit4 코드

assertEquals(expedted, actual)	

assertNotEquals(expected, actual) 

assertTrue(result instanceof String);

assertTrue(result.contains("x") || result.contains("y") || result.contains("z"))

다음과 같이 표현하면 훨씬 깔끔하고 직관적으로 코드를 작성할 수 있다. 

// Hamcrest 코드

assertThat(actual, is(equalTo(expected)));

assertThat(actual, is(not(equalTo(expected))));

assertThat(result, instanceOf(String.class));

assertThat(result, is(hasItem(anyOf(equalTo("x", equalTo("y"), equalTo("z"))))));

 


Hamcrest 패키지

org.hamcrest.core

   : 오브젝트나 값들에 대한 기본적인 Matcher들

org.hamcrest.beans

   : Java 빈(Bean)과 그 값 비교에 사용되는 Matcher들

org.hamcrest.coolection

   : 배열과 컬렉션 Matcher들

org.hamcrest.number

   : 수 비교를 하기 위한 Matcher들

org.hamcrest.object

   : 오브젝트와 클래스들 비교하는 Matcher들

org.hamcrest.test

   : 문자열 비교

org.hamcrest.xml

   : XML 문서 비교

 


코어(Core)

메소드 설명
anything 어떤 오브젝트가 사용되든 일치한다고 판별한다.
describedAs 테스트 실패 시에 보여줄 추가적인 메시지를 만들어주는 메시지 테코레이터
equalTo 두 오브텍트가 동일한지 판별한다.
Is 내부적으로 equalTo와 동일하다. 가독성 증진용. 
아래 세문장은 의미가 동일하다.
assertThat(entity, equalTo(expectedEntity));
assertThat(entity, is(equalTo(expectedEntity)));
assertThat(entity, is(expectedEntity));
// 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()));
}

 

오브젝트 (Object)

메소드 설명
hasToString toString 메소드 값과 일치 여부를 판별
typeCompatibleWith 동일 인스턴스인지 타입비교(instance of).
동일하거나 상위 클래스, 인터페이스인지 판별
notNullValue
nullValue
Null인지, 아닌지 판별
sameInstance Object가 완전히 동일한지 비교.
equals 비교가 아닌 ==(주소비교)로 비교하는 것과 동일
@Test
public void instanceOfTest() {
	int cheese = 54;
    HashMap<String, String> map1 = new HashMap<String, String>();
  
    // cheese가 null이 아니므로 통과
    assertThat(cheese, is(notNullValue()))
  
    // instance 가 다르므로 실패
    assertThat(map1, instanceOf(String.class));
    
    assertThat(map1, not(sameInstance(String.class)));
}

 

논리 (Logical)

메소드 설명
allOf 비교하는 두 오브젝트가 각각 여러 개의 다른 오브젝트를 포함하고 있을 경우에, 이를테면 collection 같은 오브젝트일 경우 서로 동일한지 판별한다. Java의 숏서킷(&& 비교)과 마찬가지로 한 부분이라도 다른 부분이 나오면 그 순간 false를 돌려준다.
anyOf allOf와 비슷하나 anyOf는 하나라도 일치하는 것이 나오면 true로 판단한다.
Java의 숏서킷(||)과 마찬가지로 한 번이라도 일치하면 true를 돌려준다.
not 서로 같지 않아야 한다.
// notnull을 기대하지 않는데 null 이므로 성공
@Test
public void notNotNullTest() {
    String str = null;
    assertThat(str,  not(notNullValue()));
}

 

빈즈 (Beans)

메소드 설명
hasProperty Java 빈즈 프로퍼티 테스트
// hasProperty 용
private String myProperty;
     
public void  setMyProperty(String property) {
    this.property = property;
}
  
// 위에 myProperty가 있으므로 성공
@Test
public void propertyTest() {
    assertThat(this, hasProperty("myProperty"));
}

 

컬렉션 (Collection)

메소드 설명
array 두 배열 내의 요소가 모두 일치하는지 판별
hasEntry,
hasKey, hasValue
맴(Map)요소에 대한 포함 여부 판단
hasItem,
hasItem
특정 요소들을 포함하고 있는지 여부 판단
hasItemInArray 배열 내에 찾는 대상이 들어 있는지 여부를 판별
@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"));
}

 

숫자 (Number)

메소드 설명
closeTo 부동소수점(floating point) 값에 대한 근사값 내 일치 여부,
값(value)과 오차(delta)를 인자로 갖는다.
greaterThan
greaterThanOrEqualTo
값 비교. >, >= OrderingComparison
lessThan
lessThanOrEqualTo
값 비교. <, <= OrderingComparison
public void hamcrestNumbersTest() {
    assertThat(2, greaterThan(1)); // 크다.
	    
    assertThat(1, greaterThanOrEqualTo(1)); // 크거나 같다.
		         
    assertThat(0, lessThan(1)); // 작다.
    assertThat(0, lessThanOrEqualTo(1)); // 작거나 같다
}

 

문자 (Text)

메소드 설명
containsString 문자열이 포함되어 있는지 여부
startsWith 특정 문자열로 시작
endsWith 특정 문자열로 종료
equalToIgnoringCase 대소문자 구분하지 않고 문자비교
equalToIgnoringWithSpace 문자열 사이의 공백 여부를 구분하지 않고 비교
@Test
public void hamcrestTextTest() {
    // 성공
    assertThat("Spring",  equalToIgnoringCase("spring"));
		  
    // 성공. 문자열 앞뒤의 공백만 무시하니 주의.
    assertThat("Spring Framework 3.2", equalToIgnoringWhiteSpace ("   Spring Framework 3.2  "));
		  
	// 성공
	assertThat("Spring Framework 3.2", containsString("Framework"));
}
 
728x90
반응형