반응형

유닛 테스트를 진행하다 보면 Matcher를 직접 구현하여 사용해야 하는 경우가 있을 수 있다.

 

이를 위해 Matcher를 custom하게 어떻게 만드는지에 대해 알아보고자 한다.

 

아래 코드에서는 FloatVlaue인지 검증하는 Matcher를 구현해보았다.

 

import org.hamcrest.Description;
import org.hamcrest.Matcher;
import org.hamcrest.TypeSafeMatcher;

public class FloatValueChecker extends TypeSafeMatcher<String> {
    /*
     * Matcher가 실제로 검증하는 로직 부분
     */
    @Override
    protected boolean matchesSafely(String value) {
        try {
            Float.parseFloat(value);
            return true;
        } catch (NumberFormatException e){
            return false;
        }
    }

    /*
     * Matcher에 적합하지 않은 경우 나타나는 경고문
     */
    @Override
    public void describeTo(Description description) {
        description.appendText("It is not float value");
    }

    /*
     * 해당 메서드를 통해 matcher를 호출 할 수 있다.
     */
    public static Matcher<String> floatValue() {
        return new FloatValueChecker();
    }
}

 

extends TypeSafeMatcher<String>를 상속하여 타입 검사에 대해 설정해주고 오버라이딩해준다.

 

이때 matchedSafely 메서드에서 내가 custom으로 구현하고자 하는 matcher의 로직을 구현해주고

 

describeTo 부분에서 실패하면 나타나는 메시지 부분을 구현해주면 된다.

 

마지막으로 floatValue라는 public method를 생성하여 해당 메서드를 호출하면 matcher가 생성되도록 해준다.

 

 

import org.junit.Test;

import static com.demo.testing.matchers.FloatValueChecker.floatValue;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.not;

public class FloatMatchersTest {

    @Test
    public void floatValueTest1() {
        String value = "1234.4";

        assertThat(value, is(floatValue()));
    }

    @Test
    public void floatValueTest2() {
        String value = "123.z";

        assertThat(value, is(not(floatValue())));
    }

    @Test
    public void floatValueTest3() {
        String value = "123.z";

        assertThat(value, is(floatValue()));
    }
}

 

결과는 아래와 같다.

 

test1,2는 pass하지만 123.z가 floatValue가 아니기 때문에 3은 실패하게 된다.

 

java.lang.AssertionError: 
Expected: is It is not float value
     but: was "123.z"

<Click to see difference>
	at org.hamcrest.MatcherAssert.assertThat(MatcherAssert.java:20)
	at org.hamcrest.MatcherAssert.assertThat(MatcherAssert.java:6)
	at com.demo.testing.matchers.FloatMatchersTest.floatValueTest3(FloatMatchersTest.java:30)
    ...
    at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:33)
	at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:230)
	at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:58)

 

반응형