본문 바로가기
Java

[Java] JUnit 5 사용법 (11) - Hamcrest

by 노력남자 2022. 9. 6.
반응형

이번 포스팅에선 이전 포스팅에 설명했던 assertions, assumptions 를 좀 더 가독성있고 편하게 쓸 수 있도록 도와주는 라이브러리 hamcrest를 소개합니다.

 

Hamcrest

 

JUnit 4 라이브러리에 포함되어 있었는데 JUnit 5로 오면서 빠지게된 라이브러리입니다.

 

spring-boot-starter-test 라이브러리에 포함되어 있습니다.

 

혹시 spring-boot-starter-test를 사용하지 않을 경우 의존성 추가해 주세요.

 

//maven
<dependency>
    <groupId>org.hamcrest</groupId>
    <artifactId>hamcrest-all</artifactId>
    <version>1.3</version>
    <scope>test</scope>
</dependency>

//gradle
testCompile group: 'org.hamcrest', name: 'hamcrest-all', version: '1.3'

 

Hamcrest에서 비교하기 위해서 assertThat 메소드 1개만을 사용합니다.

 

메소드명 설명
assertThat(T actual, Matcher<? super T> matcher) 비교 메소드

 

Matcher에 대해 알아보겠습니다.

 

Matcher는 assertThat 메소드의 첫 번째 인자로 들어온 값을 검증하기 위한 클래스입니다.

 

자주 사용하는 Matcher 위주로 정리했습니다.

(다른 Matcher들은 http://hamcrest.org/JavaHamcrest/javadoc/2.2/를 참고하시길 바랍니다.)

 

Core

 

메소드명 설명
anything() 항상 성공하는 Matcher입니다. (왜 쓰는 거죠..)
describedAs(String description, Matcher matcher,  java.lang.Object... values) decorator로 정의한 Matcher에 별도 설명이 필요할 경우 사용
is decorator로 가독성을 높혀주기 위해 사용

그냥 사용하면 = equalTo랑 동일합니다.

is(equalTo(smelly)) 와 같이 가독성을 높혀주기 위해 사용합니다.

 

예제

 

package com.effortguy.junit5.hamcrest;

import org.junit.jupiter.api.Test;

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.*;

public class hamcrestCore {

    @Test
    void testAnything() {
        assertThat("test", anything());
    }

    @Test
    void testDescribedAs () {
        assertThat("test", describedAs("for 0%", is("test"), "test"));
    }

    @Test
    void testIs() {
        assertThat("test", is("test"));
    }
}

 

결과

 

 

Logical

 

메소드명 설명
allOf(Matcher<? super T>... matchers) 모든 Matcher에 적합한 경우 성공
anyOf(Matcher<? super T>... matchers) Matcher 중 한 개만 적합해도 성공
not((Matcher<? super T> matcher) Matcher 에 적합하면 경우 실패

 

예제

 

package com.effortguy.junit5.hamcrest;

import org.junit.jupiter.api.Test;

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.*;

public class hamcrestLogical {

    @Test
    void testAllOf() {
        assertThat(true, allOf(is(true) , is(true)));
    }

    @Test
    void testAnyOf() {
        assertThat(true, anyOf(is(true) , is(false)));
    }

    @Test
    void testNot() {
        assertThat(true, not(true));
    }
}

 

결과

 

 

Object

 

메소드명 설명
equalTo Object.equals 테스트
hasToString Object.toString 테스트
instanceOf 테스트 대상의 타입 비교
isCompatibleType 타입 간 호환이 되는지 비교
notNullValue, nullValue null인지 아닌지
sameInstance 같은 Object인지 테스트

 

예제

 

package com.effortguy.junit5.hamcrest;

import org.hamcrest.object.IsCompatibleType;
import org.junit.jupiter.api.Test;

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.*;

public class hamcrestObject {

    @Test
    void testEqualTo() {
        assertThat(new String[] {"foo", "bar"}, equalTo(new String[] {"foo", "bar"}));
    }

    @Test
    void testHasToString() {
        assertThat(true, hasToString("true"));
    }

    @Test
    void testInstanceOf() {
        assertThat("test", instanceOf(String.class));
    }

    @Test
    void testIsCompatibleType() {
        assertThat(Integer.class, IsCompatibleType.typeCompatibleWith(Number.class));
    }

    @Test
    void testNullValue() {
        assertThat(null, nullValue());
    }

    @Test
    void testNotNullValue() {
        assertThat("test", notNullValue());
    }

    @Test
    void testSameInstance() {
        assertThat(new String[] {"foo", "bar"}, sameInstance(new String[] {"foo", "bar"}));
    }
}

 

결과

 

 

Beans

 

메소드명 설명
hasProperty 자바빈즈 필드 테스트

 

예제

 

package com.effortguy.junit5.hamcrest;

import org.junit.jupiter.api.Test;

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.*;

public class hamcrestBeans {

    public class Person {
        String name;
        String id;

        Person(String name, String id) {
            this.name = name;
            this.id = id;
        }

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        public String getId() {
            return id;
        }

        public void setId(String id) {
            this.id = id;
        }
    }

    @Test
    void testHasProperty() {
        Person person = new Person("peter", "spider");

        assertThat(person, hasProperty("name", is("peter")));
    }
}

 

결과

 

 

Collections

 

메소드명 설명
array 배열 항목 별 테스트
hasEntry Map 테스트, 테스트 key 값과 key 값의 value 비교
hasKey, hasValue key, value 존재 여부 테스트
hasItem, hasItems iterator 에 item 존재 여부 테스트
hasItemInArray array에 값 존재 여부 테스트

 

예제

 

package com.effortguy.junit5.hamcrest;

import org.junit.jupiter.api.Test;

import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.*;

public class hamcrestCollections {
    
    @Test
    void testArray() {
        assertThat(new Integer[]{1,2,3}, array(equalTo(1), equalTo(2), equalTo(3)));
    }

    @Test
    void testHasEntry() {
        Map<String, String> map = new HashMap<>();
        map.put("foo", "bar");

        assertThat(map, hasEntry("foo", "bar"));
        assertThat(map, hasKey("foo"));
        assertThat(map, hasValue("bar"));
    }

    @Test
    void testHasItem() {
        assertThat(Arrays.asList("foo", "bar"), hasItem(startsWith("ba")));
        assertThat(new String[] {"foo", "bar"}, hasItemInArray(startsWith("ba")));
    }
}

 

결과

 

 

Number

 

메소드명 설명
closeTo(double operand, double error) 테스트할 값과 operand의 오차가 error 이하인지 테스트

테스트 값 - operand <= error TRUE
greaterThan, greaterThanOrEqualTo 초과, 이상 테스트
lessThan, lessThanOrEqualTo 미만, 이하 테스트

 

예제

 

package com.effortguy.junit5.hamcrest;

import org.junit.jupiter.api.Test;

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.*;

public class hamcrestNumber {

    @Test
    void testCloseTo() {
        assertThat(10.5, closeTo(10, 1));
    }

    @Test
    void testGreaterThan() {
        assertThat(10, greaterThan(5));
        assertThat(10, greaterThanOrEqualTo(10));
        assertThat(10, lessThan(11));
        assertThat(10, lessThanOrEqualTo(10));
    }
}

 

결과

 

 

Text

 

메소드명 설명
equalToIgnoringCase 대소문자 무시 후 문자열 테스트
containsString 문자열 포함 여부 테스트
endsWith ~으로 끝나는지 테스트
startsWith ~으로 시작하는지  테스트

 

예제

 

package com.effortguy.junit5.hamcrest;

import org.junit.jupiter.api.Test;

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.*;

public class hamcrestText {

    @Test
    void testEqualToIgnoringCase() {
        assertThat("TeSTTEXt", equalToIgnoringCase("testtext"));
    }

    @Test
    void testContainsString() {
        assertThat("text", containsString("e"));
    }

    @Test
    void testEndsWith() {
        assertThat("text", endsWith("xt"));
        assertThat("text", startsWith("te"));
    }
}

 

결과

 

 

다음 포스팅에선 assertJ에 대해서 알아보겠습니다.

 

읽어주셔서 감사합니다.

반응형

댓글